import os, shutil
from snipper.snipper_main import censor_file
from pathlib import Path
import time
import fnmatch
import tempfile

def snip_dir(source_dir,  # Sources
             dest_dir=None,  # Will write to this directory
             output_dir=None, # Where snippets are going to be stored
             references=None, # Reference database
             exclude=None, clean_destination_dir=True,
             run_files=True,  # Run #!o tags and #!i tags
             cut_files=True,   # censor files.
             license_head=None,
             ):

    if dest_dir == None:
        dest_dir = tempfile.mkdtemp()
        print("[snipper]", "no destination dir was specified so using nonsense destination:", dest_dir)

    if references == None:
        references = dict(aux=None, bibtex=None,  commands=[])

    if exclude == None:
        exclude = []

    exclude += ["*__pycache__*"]  # Just...no.
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)

    source_dir = os.path.abspath(source_dir)
    dest_dir = os.path.abspath(dest_dir)
    if output_dir == None:
        output_dir = os.path.dirname(source_dir) + "/output"

    output_dir = os.path.abspath(output_dir)
    if os.path.samefile( source_dir, dest_dir):
        raise Exception("Source and destination is the same")

    if clean_destination_dir:
        shutil.rmtree(dest_dir)
    os.makedirs(dest_dir)

    out = dest_dir
    hw = {'base': source_dir}

    print(f"[snipper] Synchronizing directories: {hw['base']} -> {out}")
    if os.path.exists(dest_dir):
        shutil.rmtree(dest_dir)

    shutil.copytree(source_dir, dest_dir)
    time.sleep(0.1)

    ls = list(Path(dest_dir).glob('**/*.*'))
    acceptable = []
    for l in ls:
        split = os.path.normpath(os.path.relpath(l, dest_dir))
        m = [fnmatch.fnmatch(split, ex) for ex in exclude]
        acceptable.append( (l, not any(m) ))

    # for f,ac in acceptable:
    #     if not ac:
    #         print(f)

    # print(acceptable)
    # now we have acceptable files in list.
    # run_out_dirs = ["./output"]
    n = 0
    # edirs = [os.path.join(out, f_) for f_ in hw['exclusion']]  # Exclude directories on exclude list (speed)
    # edirs = {os.path.normpath(os.path.dirname(f_) if not os.path.isdir(f_) else f_) for f_ in edirs}
    # edirs.remove(os.path.normpath(out))
    for f, accept in acceptable:
        if os.path.isdir(f) or not str(f).endswith(".py") or  str(f).endswith("_grade.py"): # We only touch .py files.
            continue
        # f_dir = os.path.normpath(f if os.path.isdir(f) else os.path.dirname(f))
        if accept:
            # slist = hw['solutions'] if not CE else [os.path.basename(f)[:-3]]
            # base = None
            # if students_irlc_tools is not None:
            #     base = os.path.relpath(str(f), students_irlc_tools + "/..")
            #     base = base.replace("\\", "/")

            # if "assignments" in str(f) and "_grade.py" in str(f):
            #     continue
            # info = {'new_references': [], 'code_copyright': 'Example student code. This file is automatically generated from the files in the instructor-directory'}
            # paths = {}
            solution_list = []
            kwargs = {}
            # cut_files = True
            # copyright()

            # run_files = True
            nrem = censor_file(f, run_files=run_files, run_out_dirs=output_dir, cut_files=cut_files, solution_list=solution_list,
                               base_path=dest_dir,
                               references=references,
                               license_head=license_head,
                               **kwargs)
            if nrem > 0:
                print(f"{nrem}> {f}")
            n += nrem
    for rm_file, accept in acceptable:
        rm_file = os.path.abspath(rm_file)
        if not accept:
            if os.path.isfile(rm_file):
                os.remove(rm_file)
            else:
                if os.path.isdir(rm_file + "\\"):
                    shutil.rmtree(rm_file)

    return n
