"""
Copyright (c) 2025 Silicon Laboratories Inc.

SPDX-License-Identifier: Apache-2.0
"""
import argparse
import re
import datetime
from pathlib import Path

devices = {
	"xg21": {
		"bits": "platform/Device/SiliconLabs/EFR32MG21/Include/efr32mg21_acmp.h",
  },
	"xg23": {
		"bits": "platform/Device/SiliconLabs/EFR32FG23/Include/efr32fg23_acmp.h",
  },
	"xg24": {
		"bits": "platform/Device/SiliconLabs/EFR32MG24/Include/efr32mg24_acmp.h",
  },
	"xg27": {
		"bits": "platform/Device/SiliconLabs/EFR32BG27/Include/efr32bg27_acmp.h",
  },
	"xg29": {
		"bits": "platform/Device/SiliconLabs/EFR32MG29/Include/efr32mg29_acmp.h",
  },
}

if __name__ == "__main__":
  parser = argparse.ArgumentParser(description="Generate headers for Comparator for Series 2 "
                                   "devices. The headers are used from DeviceTree, and represent "
                                   "every ACMP input selection as a DT compatible macro.")
  parser.add_argument("--out", "-o", type=Path, default=Path(__file__).parent / "out",
                      help="Output directory. Defaults to the directory ./out/ relative to the "
                      "script. Set to $ZEPHYR_BASE/include/zephyr/dt-bindings/comparator/ "
                      "to directly generate output into the expected location within the Zephyr "
                      "main tree.")
  parser.add_argument("--sdk", "-s", type=Path, default=Path(__file__).parent.parent / "simplicity_sdk",
                      help="Path to Simplicity SDK to extract data from. Defaults to the directory "
                       "../simplicity_sdk relative to the script.")
  args = parser.parse_args()

  args.out.mkdir(exist_ok=True)

  defines = {} 
  for device, data_sources in devices.items():
    bits_file = (args.sdk / data_sources["bits"]).resolve()
    with bits_file.open() as f:
      for line in f:

        if m := re.match(r"#define (_ACMP_INPUTCTRL_POSSEL_(?!SHIFT)(?!MASK)(?!DEFAULT).*)\s+(\dx[\dABCDEF]+)", line):
          input_value = hex(int(m.group(2),16))
          input_name = f"#define ACMP_INPUT_{m.group(1).split('_')[-1]}"
          # Detect any input definition collisions
          if (input_value in defines):
              if ( input_name == defines[input_value] ):
                  print(f"Inputs {input_name} and {defines[input_value]} share the same value {input_value}.")
          defines.update({input_value : f"{input_name} {input_value}"})

        if m := re.match(r"#define (_ACMP_INPUTCTRL_NEGSEL_(?!SHIFT)(?!MASK)(?!DEFAULT).*)\s+(\dx[\dABCDEF]+)", line):
          input_value = hex(int(m.group(2),16))
          input_name = f"#define ACMP_INPUT_{m.group(1).split('_')[-1]}"
          # Detect any input definition collisions
          if (input_value in defines):
              if ( input_name == defines[input_value] ):
                  print(f"Inputs {input_name} and {defines[input_value]} share the same value {input_value}.")
          defines.update({input_value : f"{input_name} {input_value}"})

  # Sort defines by key
  defines = dict(sorted(defines.items()))

  file = [
    "/*",
    f" * Copyright (c) {datetime.date.today().year} Silicon Laboratories Inc.",
    " *",
    " * SPDX-License-Identifier: Apache-2.0",
    " *",
    f" * This file was generated by the script {Path(__file__).name} in the hal_silabs module.",
    " * Do not manually edit.",
    " */",
    "",
    f"#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_COMPARATOR_SILABS_ACMP_H_",
    f"#define ZEPHYR_INCLUDE_DT_BINDINGS_COMPARATOR_SILABS_ACMP_H_",
    "",
    f"/* ACMP Input Aliases */",
    f"#define ACMP_INPUT_VDACOUT0 ACMP_INPUT_VDAC0OUT0",
    f"#define ACMP_INPUT_VDACOUT1 ACMP_INPUT_VDAC0OUT1",
    "",
    f"/* ACMP Input Definitions */",
  ] + list(defines.values()) + [
    "",
    f"#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_COMPARATOR_SILABS_ACMP_H_ */",
    "",
  ]

  outfile = args.out / f"silabs-acmp.h"
  outfile.write_text("\n".join(file))
