import os
import hashlib
import pathlib
import shlex
import subprocess


import SCons.Action
from platformio import fs

from pathlib import Path

Import("env")

# We don't use `env.Execute` because it does not handle spaces in path
# See https://github.com/nanopb/nanopb/pull/834
# So, we resolve the path to the executable and then use `subprocess.run`
python_exe = env.subst("$PYTHONEXE")

try:
    import nunavut
except ImportError:
    print("[nunavut] Installing")
    subprocess.run([python_exe, '-m', 'pip', 'install', "nunavut"])
    import nunavut

import pydsdl
import subprocess

def run_nnvg(asset, lookup, generated_src_dir):

    # Define the command as a list of arguments
    cmd = [
        "nnvg",
        "--target-language", "c",
        "--enable-serialization-asserts",
        f"{asset}",  # The input DSDL namespace directory
        "--outdir", f"{generated_src_dir}",
    ]
    if len(lookup) > 0:
        cmd.extend(["--lookup-dir", f"{lookup}"])    
    result = subprocess.run(cmd, text=True, capture_output=True)
    print("running", " ".join(cmd))
    err = str(result.stderr) 
    if len(err.strip()) > 0:
        print("nnvg ERROR:\n", result.stderr)

project_dir = env.subst("$PROJECT_DIR")

build_dir = env.subst("$BUILD_DIR")

generated_src_dir = os.path.join(build_dir, 'nunavut', 'generated-src')
generated_src_dir = os.path.join(project_dir, 'include')
print("generated_src_dir",generated_src_dir)
generated_build_dir = os.path.join(build_dir, 'nunavut', 'generated-build')
md5_dir = os.path.join(build_dir, 'nunavut', 'md5')

dsdl_folders = [x for x in env.subst(env.GetProjectOption("custom_dsdl_folders", "")).split("\n") if x != ""]
print(dsdl_folders)
from pathlib import Path
def generate_dsdl_files(*args, **kwargs):
    if not dsdl_folders:
        print("[nunavut] No generation needed.")
    else:
        parent_folder = Path(project_dir)
        print("parent_folder", parent_folder)
        uavcan_dir = None
        for path in parent_folder.rglob("*"):
            #if path.is_dir() and path.name in dsdl_folders:
            if path.is_dir() and path.name in ["uavcan"]:
                uavcan_dir = (str(path.absolute()))
                #uavcan_dir = (str(path.relative_to(project_dir)))
                print("found uavcan dir:", uavcan_dir)
        
        for path in parent_folder.rglob("*"):
            #if path.is_dir() and path.name in dsdl_folders:
            if path.is_dir() and any([str(path.absolute()).endswith(d) for d in dsdl_folders]) :
                run_nnvg(path.absolute(), uavcan_dir, generated_src_dir)
        #
        # Add generated includes and sources to build environment
        #
        run_nnvg(uavcan_dir, "", generated_src_dir)
        env.Append(CPPPATH=[generated_src_dir])
        env.Append(CXXFLAGS=[f"-I{generated_src_dir}", "flag2"])
        #env.BuildSources(generated_build_dir, generated_src_dir)

        # # Fix for ESP32 ESP-IDF https://github.com/nanopb/nanopb/issues/734#issuecomment-1001544447
        # global_env = DefaultEnvironment()
        # already_called_env_name = "_PROTOBUF_GENERATOR_ALREADY_CALLED_" + env['PIOENV'].replace("-", "_")
        # if not global_env.get(already_called_env_name, False):
        #     env.BuildSources(generated_build_dir, generated_src_dir)
        # global_env[already_called_env_name] = True



#env.AddCustomTarget("gen_dsdl", None, generate_dsdl_files)
generate_dsdl_files()
#env.AddPreAction("buildprog", generate_dsdl_files)