import sys, os, shutil, filecmp

# Arguments
pyb11_mod_name = sys.argv[1]
mod_name = sys.argv[2]
multiple_files = eval(sys.argv[3])
generatedfiles = sys.argv[4]
allow_skips = eval(sys.argv[5])
default_holder_type = sys.argv[6]
is_submodule = eval(sys.argv[7])
submodules = sys.argv[8]
dry_run = eval(sys.argv[9])

if submodules == "False":
   submodules = []
else:
   submodules = submodules.split(";")

# Prepare output directories
current_pth = "current_" + mod_name
new_pth     = "new_"     + mod_name
if not dry_run:
   if not os.path.exists(current_pth):
       os.makedirs(current_pth)
   if os.path.exists(new_pth):
       shutil.rmtree(new_pth)
   os.makedirs(new_pth)

# Paths to the main module pybind11 source files
current_src = os.path.join(current_pth, mod_name + ".cc")
new_src     = os.path.join(new_pth,    mod_name + ".cc")

# Generate the source anew 
code = f"""
from PYB11Generator import *
import {pyb11_mod_name}
PYB11generateModule({pyb11_mod_name}, 
                    modname = \"{mod_name}\",
                    filename = \"{new_src}\",
                    multiple_files = {multiple_files},
                    generatedfiles = \"{generatedfiles}\",
                    default_holder_type = \"{default_holder_type}\",
                    is_submodule = {is_submodule},
                    submodules = {submodules},
                    dry_run = {dry_run})
"""
exec(code)
assert os.path.isfile(generatedfiles)

# Are we actually generating code or is this a dry run to just get the generated file names?
if not dry_run:
    assert os.path.isfile(new_src)

    # Look for any files we want to preserve from the existing generated pybind11 source
    skips = []
    if allow_skips:
        # Scan to see if any of the current files should be preserved
        current_files = os.listdir(current_pth)
        for filename in current_files:
            with open(os.path.join(current_pth, filename), "r") as f:
                line = f.readline().strip()
                if line.startswith("// PYB11skip"):
                    skips.append(filename)
                    print("PYB11Generator WARNING: skipping regenerating {} as requested".format(filename))

    # Compare the old and new generated files
    diff = filecmp.dircmp(current_pth, new_pth)

    # Copy any new files or changed files
    for filename in diff.right_only + diff.diff_files:
        if not filename in skips:
            shutil.copy(os.path.join(new_pth, filename),
                        os.path.join(current_pth, filename))

    # Remove any files not in the new set
    for filename in diff.left_only:
        if not filename in skips:
            os.remove(os.path.join(current_pth, filename))

    # Clean up the temporary new file path
    shutil.rmtree(new_pth)

    assert os.path.isfile(current_src)
    assert not os.path.exists(new_pth)
