# SPDX-License-Identifier: GPL-2.0-or-later
# PDKMaster & co. don't put a license requirement on the generated files.
# The generated gds files in this project are released under the LGPL 2.0 or later license.
from pathlib import Path
from typing import Any, cast

import pya as _pya
# Disable type checking
pya = cast(Any, _pya)

from pdkmaster.technology import geometry as _geo
from pdkmaster.design import library as _lib
from pdkmaster.io.klayout import export as _klexp

from c4m.pdk import sky130

from . import frame as _frm, sram as _ram, bandgap as _bg


__all__ = ["gen_gds"]


def _postprocess(*, klay: "pya.Layout"):
    # Post process
    # - split tapdiff into tap and diff layers
    # - remove pad drawing layer to avoid interacting with RDL
    nwell_idx = klay.layer(64, 20)
    diff_idx = klay.layer(65, 20)
    tap_idx = klay.layer(65, 44)
    nsdm_idx = klay.layer(93, 44)
    psdm_idx = klay.layer(94, 20)
    pad_idx = klay.layer(76, 20)

    for cell in klay.each_cell():
        nwell = pya.Region(cell.shapes(nwell_idx))
        nsdm = pya.Region(cell.shapes(nsdm_idx))
        psdm = pya.Region(cell.shapes(psdm_idx))

        tap_cover = (nsdm & nwell) + (psdm - nwell)

        diff_shapes = cell.shapes(diff_idx)
        tap_shapes = cell.shapes(tap_idx)

        difftap = pya.Region(cell.shapes(diff_idx)) # Original difftap layer to be split

        tap = difftap & tap_cover
        diff = difftap - tap

        diff_shapes.clear()
        diff_shapes.insert(diff)
        tap_shapes.insert(tap)

        cell.shapes(pad_idx).clear()


def gen_gds(*, name: str, gds_out: Path, gds_empty: Path):
    top_name = "user_analog_project_wrapper"

    lib = _lib.Library(
        name=name, tech=sky130.tech, cktfab=sky130.cktfab, layoutfab=sky130.layoutfab,
    )

    # Create user_analog_project_wrapper top cell
    top = lib.new_cell(name=top_name)
    ckt = top.new_circuit()
    layouter = top.new_circuitlayouter()

    # Add the BandGap
    bandgap_cell = _bg.ConnectedBandGap(lib=lib)
    bandgap_inst = ckt.instantiate(bandgap_cell, name="bandgaptop")
    layouter.place(bandgap_inst, x=0.0, y=0.0)

    # Add the SRAM
    sram_cell = _ram.ConnectedSRAM(lib=lib)
    sram_inst = ckt.instantiate(sram_cell, name="sramtop")
    layouter.place(sram_inst, origin=_geo.origin)

    lib.cells += (bandgap_cell, sram_cell)

    # Add circuit and
    layouter.layout.boundary = _frm.boundary

    # Convert to klayout
    klay = _klexp.export2db(
        obj=lib, add_pin_label=True, gds_layers=sky130.gds_layers, cell_name=None, merge=True,
    )

    _postprocess(klay=klay)

    # Instantiate the empty cell in top cell
    emptylib = pya.Library()
    emptylib.register("empty")
    emptylayout = emptylib.layout()
    emptylayout.read(str(gds_empty))
    emptylibcell_idx = emptylayout.cell("user_analog_project_wrapper_empty").cell_index()
    emptycell_idx = klay.add_lib_cell(emptylib, emptylibcell_idx)

    ktop = klay.cell(top_name)
    ktop.insert(pya.CellInstArray(emptycell_idx, pya.Trans.R0))

    ktech = pya.Technology.technology_by_name("Skywater_S8")
    ksaveopts = ktech.save_layout_options.dup()
    ksaveopts.write_context_info = False
    klay.write(str(gds_out), ksaveopts)
