"""Length matching — equalize optical path lengths across channels.

Two arms with different physical paths. `match_length_to(other)` adds a
single U-meander to the shorter arm so its total length equals the
longer arm's length. Critical for MZI arms, parallel fiber arrays, and
any interferometer-style geometry.
"""
import lumicron as lm
import lumicron.pdks.elyon_demo.all as pdk


@lm.pcell
def LengthMatch(pitch: float = 50.0):
    c = lm.CELL("LengthMatch")

    for i in range(2):
        y = i * pitch
        c.add(lm.PORT(f"a{i}", position=(0, y), direction=0,
                      route_profile=pdk.RP.silc_strip))
        c.add(lm.PORT(f"b{i}", position=(800, y), direction=180,
                      route_profile=pdk.RP.silc_strip))

    # Bottom arm jogs south then back — makes it the longer reference.
    bot = (c.Route(c.ports["a0"], radius=15).to(c.ports["b0"])
           .jog("S", by=80))

    # Top arm: straight, then matches bot's length with an auto U-bend.
    (c.Route(c.ports["a1"], radius=15).to(c.ports["b1"])
        .match_length_to(bot))
    return c


if __name__ == "__main__":
    LengthMatch().to_gds("length_match.gds")
