import os
import json
import shutil
from subprocess import PIPE, run
import sys

GAME_DIR_PATTERN = "game"
GAME_CODE_EXTENSION = ".go"
GAME_COMPILE_COMMAND = ["go", "build"]

def find_all_game_paths(source):
    game_paths = []
    
    for root, dirs, files in os.walk(source):
        for directory in dirs:
            if GAME_DIR_PATTERN in directory.lower():
                path = os.path.join(source, directory)
                game_paths.append(path)
        break
    return game_paths


def get_name_from_paths(paths, to_strip):
    new_names = []
    for path in paths:
        _, dir_name = os.path.split(path)
        new_dir_name = dir_name.replace(to_strip, "")
        new_names.append(new_dir_name)
    return new_names


def create_dir(path):
    if not os.path.exists(path):
        os.mkdir(path)


def copy_and_overwrite(source, dest):
    if os.path.exists(dest):
        shutil.rmtree(dest) # remove tree (recursive delete)
    shutil.copytree(source, dest) # copy source to destination
    pass


def make_json_metadata_file(path, game_dirs):
    data = {
        "gameName": game_dirs,
        "numberOfGames": len(game_dirs)
    }
    with open(path, "w") as f:
        json.dump(data, f)


def compile_game_code(path):
    code_file_name = None
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(GAME_CODE_EXTENSION): # Avoids possible issues of .go.txt etc.
                code_file_name = file
                break
        break
    
    if code_file_name is None:
        return
    
    command = GAME_COMPILE_COMMAND + [code_file_name] # Run the go command
    run_command(command, path)

def run_command(command, path):
    cwd = os.getcwd()
    os.chdir(path)
    
    result = run(command, stdout=PIPE, stdin=PIPE, universal_newlines=True)
    # print("compile result", result)
    '''
    PIPE creates a bridge for the python code to be interpreted when
    running a custom command. Essentially creates a .exe(.sh for linux/mac)
    to be able to run the game.
    If an errors occurs when compiling, the stdout will print it.
    '''

    os.chdir(cwd)


def main(source, target):
    # Get full folder path to avoid bugs in differing OS
    cwd = os.getcwd()
    source_path = os.path.join(cwd, source)
    target_path = os.path.join(cwd, target)

    game_paths = find_all_game_paths(source_path)
    # print(game_paths)
    new_game_dirs = get_name_from_paths(game_paths, "_game")
    # print(new_game_dirs)

    create_dir(target_path)
    
    # Loop through all game paths and copy them over to the destination
    for src, dest in zip(game_paths, new_game,dirs): 
        dest_path = os.path.join(target_path, dest)
        copy_and_overwrite(src, dest_path)
        compile_game_code(dest_path)
    '''
    How zip works
    Takes matching elements from two arrays and turns it into a tuple
    [1,2,3]
    ["a", "b", "c"]
    (1,"a"), (2,"b"), (3,"c")
    '''

    json_path = os.path.join(target_path, "metadata.json")
    make_json_metadata_file(json_path, new_game_dirs)


# Makes sure the file is run directly
# Also stops the entire file from being loaded 
if __name__ == "__main__":
    args = sys.argv
    # print(args)
    if len(args) != 3: # Confirm 3 arguments are input
        raise Exception("You must pass a source and target directory - only.")

    # Takes the two other arguments and assigns them
    source, target = args[1:]
    main(source, target)