# 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


__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 SRAM
    sram_cell = _ram.ConnectedSRAM(lib=lib)
    sram_inst = ckt.instantiate(sram_cell, name="sramtop")
    layouter.place(sram_inst, origin=_geo.origin)

    # 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)
