import argparse
import json
import os
import shutil

parser = argparse.ArgumentParser(
    description='Rebuilds an m3u playlist.'
)

parser.add_argument(
    "playlist",
    type=argparse.FileType(),
    help="The playlist to rebuild."
)

parser.add_argument(
    "patches",
    type=argparse.FileType(),
    help="The patches file to apply to the playlist."
)

parser.add_argument(
    "output_playlist",
    type=argparse.FileType('w'),
    help="The output file to write the rebuilt playlist to. Must be in the same directory as the original playlist."
)

parser.add_argument(
    "output_dir",
    type=str,
    help="The directory to copy the unmodified-in-m3u output files to (relative to the output playlist)."
)

args = parser.parse_args()

# Get the directory of the output playlist file
output_playlist_dir = os.path.dirname(args.output_playlist.name)
output_files_dir = os.path.join(output_playlist_dir, args.output_dir)

# Make sure playlist and output are in the same directory
if output_playlist_dir != os.path.dirname(args.playlist.name):
    parser.error("The output playlist and the original playlist must be in the same directory.")

# Make sure the output directory exists
if not os.path.exists(output_files_dir):
    os.makedirs(output_files_dir)

# Get the directory of the playlist file
playlist_dir = os.path.dirname(args.playlist.name)

# Read the playlist file, and store the lines in a list
with args.playlist as f:
    playlist_lines = f.readlines()

# Remove lines that are empty or start with a # (extended m3u comment/data)
playlist_lines = [line for line in playlist_lines if line and not line.startswith("#")]

# Read the patches file, and store as json object
with args.patches as f:
    patches = json.load(f)
    patches_map = { patch['source']: patch['target'] for patch in patches }

# Output playlist
output_playlist = []

# Apply the patches to the playlist
for line in playlist_lines:
    if line in patches_map:
        if not os.path.exists(os.path.join(playlist_dir, patches_map[line])):
            print("WARNING: File not found: " + patches_map[line])
        line = patches_map[line]
    else:
        # Copy the file to the output directory
        file_path = str(os.path.join(playlist_dir, line.strip()))
        new_path = str(os.path.join(str(output_files_dir), os.path.basename(file_path)))
        os.makedirs(os.path.dirname(new_path), exist_ok=True)
        shutil.copy(file_path, new_path)
        line = os.path.join(args.output_dir, os.path.basename(file_path))

# Write the output playlist
with args.output_playlist as f:
    f.writelines(output_playlist)

print("Rebuilt playlist written to " + args.output_playlist.name)