import bpy
import os 
import json
import pathlib

def prepare_auto_export(auto_export_overrides={}, gltf_export_settings = {"export_animations": False, "export_optimize_animation_size": False}):
    # with change detection
    # first, configure things
    # we use the global settings for that
    export_props = {
        "level_scene_names" : ['World'],
        "library_scene_names": ['Library'],
        **auto_export_overrides
    }
  
    # store settings for the auto_export part
    stored_auto_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings")
    stored_auto_settings.clear()
    stored_auto_settings.write(json.dumps(export_props))

    gltf_settings = gltf_export_settings
    # and store settings for the gltf part
    stored_gltf_settings = bpy.data.texts[".blenvy_gltf_settings"] if ".blenvy_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".blenvy_gltf_settings")
    stored_gltf_settings.clear()
    stored_gltf_settings.write(json.dumps(gltf_settings))

def run_auto_export(setup_data):
    auto_export_operator = bpy.ops.export_scenes.auto_gltf
    auto_export_operator(
        auto_export=True,
        direct_mode=True,
        project_root_path = os.path.abspath(setup_data["root_path"]),
        export_output_folder="./models",
        match_blender_visuals=True,
        export_blueprints=True,
        split_out_materials=False
    )

    levels_path = setup_data["levels_path"]
    level_file_paths = list(map(lambda file_name: os.path.join(levels_path, file_name), sorted(os.listdir(levels_path)))) if os.path.exists(levels_path) else []

    blueprints_path = setup_data["blueprints_path"]
    blueprints_file_paths = list(map(lambda file_name: os.path.join(blueprints_path, file_name), sorted(os.listdir(blueprints_path)))) if os.path.exists(blueprints_path) else []

    modification_times = list(map(lambda file_path: os.path.getmtime(file_path), blueprints_file_paths + level_file_paths))
    # assert os.path.exists(world_file_path) == True

    mapped_files_to_timestamps_and_index = {}
    for (index, file_path) in enumerate(blueprints_file_paths + level_file_paths):
        file_path = pathlib.Path(file_path).stem
        mapped_files_to_timestamps_and_index[file_path] = (modification_times[index], index)

    return (modification_times, mapped_files_to_timestamps_and_index)

def run_auto_export_and_compare(setup_data, changes, expected_changed_files = []):
    (modification_times_first, mapped ) = run_auto_export(setup_data)   
    for index, change in enumerate(changes):
        change()
        (modification_times, mapped ) = run_auto_export(setup_data)   

        changed_files = expected_changed_files[index]
        changed_file_indices =  [mapped[changed_file][1] for changed_file in changed_files]
        print("changed files", changed_files, changed_file_indices, "mapped", mapped)
        other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in changed_file_indices]
        other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in changed_file_indices]

        print("other_files_modification_times_new  ", other_files_modification_times)
        print("other_files_modification_times_first", other_files_modification_times_first)
        for changed_file_index in changed_file_indices:
            #print("modification_times_new  [changed_file_index]", modification_times[changed_file_index])
            #print("modification_times_first[changed_file_index]", modification_times_first[changed_file_index])
            if changed_file_index in modification_times_first and changed_file_index in modification_times:
                assert modification_times[changed_file_index] != modification_times_first[changed_file_index], f"failure in change: {index}, at file {changed_file_index}"
            # TODO: we should throw an error in the "else" case ?
        assert other_files_modification_times == other_files_modification_times_first ,  f"failure in change: {index}"
        
        # reset the comparing 
        modification_times_first = modification_times