// Copyright 2020 Project U-Ray Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dev.fpga.rapidwright;

import com.xilinx.rapidwright.design.*;
import com.xilinx.rapidwright.design.tools.LUTTools;
import com.xilinx.rapidwright.device.*;
import com.xilinx.rapidwright.edif.EDIFPortInst;
import com.xilinx.rapidwright.edif.EDIFPropertyValue;
import com.xilinx.rapidwright.edif.EDIFValueType;
import jnr.ffi.annotations.In;
import org.json.Property;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;

public class dump_features {

    static String site_index_in_tile(Tile t, Site s) {
        int min_x = s.getInstanceX(), min_y = s.getInstanceY();
        for (Site s2 : t.getSites()) {
            if (s2.getSiteTypeEnum() == s.getSiteTypeEnum()) {
                min_x = Math.min(min_x, s2.getInstanceX());
                min_y = Math.min(min_y, s2.getInstanceY());
            }
        }
        return s.getSiteTypeEnum().toString() + "_X" + (s.getInstanceX() - min_x) + "Y" + (s.getInstanceY() - min_y);
    }

    static HashSet<String> inverted_pips = new HashSet<>();

    static boolean is_sink_inverted(SitePinInst spi) {
        if (spi == null || spi.getNet() == null)
            return false;
        Net n = spi.getNet();
        HashMap<Node, PIP> pip_uphill = new HashMap<>();
        for (PIP p : n.getPIPs()) {
            pip_uphill.putIfAbsent(p.getEndNode(), p);
            if (p.isBidirectional()) {
                pip_uphill.putIfAbsent(p.getStartNode(), p);
            }
        }
        boolean inv = false;
        Node cursor = spi.getConnectedNode();
        while (pip_uphill.containsKey(cursor)) {
            PIP p = pip_uphill.get(cursor);
            String name = p.getTile().getName() + "/" + p.getTile().getTileTypeEnum().toString() + "." + p.getStartWireName() + (p.isBidirectional() ? "<<->>" : "->>") + p.getEndWireName();
            if (inverted_pips.contains(name))
                inv = !inv;
            //System.out.println(name + " " + inv);
            if (p.isBidirectional() && p.getStartNode().equals(cursor))
                cursor = p.getEndNode();
            else
                cursor = p.getStartNode();
        }
        return inv;
    }

    public static void main(String[] args) throws IOException {


        Scanner scanner = new Scanner(new File("/invpips.txt"));
        while (scanner.hasNextLine()) {
            String nl = scanner.nextLine().trim();
            inverted_pips.add(nl);
        }

        File folder = new File("/specimen");
        File[] listOfFiles = folder.listFiles();
        for (File f : listOfFiles) {
            if (f.getName().endsWith(".dcp")) {
                Design des = Design.readCheckpoint(f.getAbsolutePath());
                HashMap<String, ArrayList<String>> pips_by_tile = new HashMap<>();
                HashMap<String, ArrayList<String>> sitefeatures_by_tile = new HashMap<>();
                for (Net n : des.getNets()) {

                    HashMap<Node, PIP> uphill = new HashMap<>();
                    HashSet<Node> allnodes = new HashSet<>();

                    if (n.getSource() != null)
                        uphill.put(n.getSource().getConnectedNode(), null);
                    for (PIP p : n.getPIPs()) {
                        uphill.put(p.getEndNode(), p);
                        allnodes.add(p.getStartNode());
                        allnodes.add(p.getEndNode());
                    }

                    for (Node node : allnodes) {
                        for (Wire w : node.getAllWiresInNode()) {
                            TileTypeEnum wtt = w.getTile().getTileTypeEnum();
                            if (wtt == TileTypeEnum.RCLK_BRAM_INTF_L || wtt == TileTypeEnum.RCLK_BRAM_INTF_TD_L || wtt == TileTypeEnum.RCLK_BRAM_INTF_TD_R ||
                                wtt == TileTypeEnum.RCLK_CLEL_L_L || wtt == TileTypeEnum.RCLK_CLEL_L || wtt == TileTypeEnum.RCLK_CLEL_L_R ||
                                    wtt == TileTypeEnum.RCLK_CLEM_CLKBUF_L || wtt == TileTypeEnum.RCLK_CLEM_L || wtt == TileTypeEnum.RCLK_DSP_INTF_L) {
                                if (w.getWireName().startsWith("CLK_TEST_BUF_SITE_") || w.getWireName().startsWith("CLK_HROUTE_CORE_OPT")) {
                                    String tile = w.getTile().getName() + ":" + w.getTile().getTileTypeEnum().toString();
                                    if (!pips_by_tile.containsKey(tile))
                                        pips_by_tile.put(tile, new ArrayList<>());
                                    pips_by_tile.get(tile).add("WIRE." + w.getWireName() + ".USED");

                                }
                            }
                            if (wtt == TileTypeEnum.RCLK_DSP_INTF_CLKBUF_L || wtt == TileTypeEnum.RCLK_CLEM_CLKBUF_L || wtt == TileTypeEnum.RCLK_BRAM_INTF_L) {
                                if (w.getWireName().startsWith("CLK_HROUTE") || w.getWireName().startsWith("CLK_HDISTR") ) {
                                    String tile = w.getTile().getName() + ":" + w.getTile().getTileTypeEnum().toString();
                                    if (!pips_by_tile.containsKey(tile))
                                        pips_by_tile.put(tile, new ArrayList<>());
                                    pips_by_tile.get(tile).add("WIRE." + w.getWireName() + ".USED");
                                }
                            }
                        }
                    }

                    for (PIP p : n.getPIPs()) {

                        String tile = p.getTile().getName() + ":" + p.getTile().getTileTypeEnum().toString();
                        TileTypeEnum ptt = p.getTile().getTileTypeEnum();
                        if (ptt == TileTypeEnum.BRAM)
                            continue;
                        if (!pips_by_tile.containsKey(tile))
                            pips_by_tile.put(tile, new ArrayList<>());
                        if (ptt == TileTypeEnum.INT_INTF_L_IO) {
                            if (p.getEndWireName().contains("LOGIC_OUTS"))
                                pips_by_tile.get(tile).add("WIRE.LOGIC_OUTS_R.DRIVEN");
                            continue;
                        }
                        if (p.isBidirectional()) {
                            boolean is_fwd = uphill.containsKey(p.getStartNode());
                            pips_by_tile.get(tile).add("PIP." + p.getEndWireName() + "." + p.getStartWireName() + (is_fwd ? ".FWD" : ".REV"));
                        } else {
                            pips_by_tile.get(tile).add("PIP." + p.getEndWireName() + "." + p.getStartWireName());
                        }
                    }
                }
                for (SiteInst si : des.getSiteInsts()) {
                    String tile = si.getTile().getName() + ":" + si.getTile().getTileTypeEnum().toString();
                    if (!sitefeatures_by_tile.containsKey(tile))
                        sitefeatures_by_tile.put(tile, new ArrayList<>());
                    ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
                    if (si.getSiteTypeEnum() == SiteTypeEnum.SLICEL || si.getSiteTypeEnum() == SiteTypeEnum.SLICEM) {
                        boolean[] clkinv = {false, false}, srinv = {false, false}, ffsync = {false, false}, latch = {false, false};
                        boolean[] haveff = {false, false};
                        boolean[] srused = {false, false, false, false};
                        boolean[] ceused = {false, false, false, false};

                        for (BEL b : si.getBELs()) {
                            String belName = b.getName();
                            Cell c = si.getCell(b);
                            if (c == null)
                                continue;

                            if (belName.contains("LUT")) {
                                if (c.getType().startsWith("RAM")) {
                                    tfeat.add(belName.replaceAll("[56]", "") + ".RAM");
                                    if (c.getType().contains("32"))
                                        tfeat.add(belName.replaceAll("[56]", "") + ".RAM.SMALL");
                                    else
                                        tfeat.add(belName.replaceAll("[56]", "") + ".RAM.LARGE");
                                }
                                if (c.getType().contains("SRL"))
                                    tfeat.add(belName.replaceAll("[56]", "") + ".SRL");
                                if (c.getType().contains("SRL16"))
                                    tfeat.add(belName.replaceAll("[56]", "") + ".SRL.SMALL");
                                if (c.getType().contains("SRLC32"))
                                    tfeat.add(belName.replaceAll("[56]", "") + ".SRL.LARGE");

                                for (int i = 6; i <= 8; i++) {
                                    if (c.getPhysicalPinMapping("WADR" + i) != null)
                                        tfeat.add("WA" + (i+1) + "USED");
                                }
                                if (c.getType().contains("SRLC32") && c.getEDIFCellInst() != null) {
                                    EDIFPortInst epi = c.getEDIFCellInst().getPortInst("D");
                                    if (epi != null && c.getPhysicalPinMapping("D") != null)
                                        tfeat.add(belName.replaceAll("[56]", "") + ".DI1." + c.getPhysicalPinMapping("D"));
                                } else if (c.getLogicalPinMapping("DI1") != null) {
                                    tfeat.add(belName.replaceAll("[56]", "") + ".DI1.DI1");
                                }
                                if ((c.getType().contains("RAM") || c.getType().contains("SRL")) && c.getEDIFCellInst() != null && c.getProperty("IS_CLK_INVERTED") != null) {
                                    String lclkinv = c.getProperty("IS_CLK_INVERTED").getValue();
                                    tfeat.add("LCLKINV." + lclkinv.substring(lclkinv.length() - 1));
                                }

                            }

                            var p2l = c.getPinMappingsP2L();
                            if (belName.contains("LUT") && c.getEDIFCellInst() != null && c.getProperty("INIT") != null) {
                                boolean has_56lut = false;
                                if (belName.contains("6LUT") && si.getCell(si.getBEL(belName.replace('6', '5'))) != null)
                                    has_56lut = true;
                                if (!has_56lut && (c.getType().startsWith("LUT"))) {
                                    // LUT init bits
                                    long long_init = LUTTools.getInitValue(c.getProperty("INIT").getValue());
                                    for (int i = 0; i < 64; i++) {
                                        if (belName.contains("5LUT") && (i >= 32))
                                            continue;
                                        String sw = belName.substring(0, 1) + "6";
                                        Net sn = si.getNetFromSiteWire(sw);
                                        if (belName.contains("6LUT") && sn != null && sn.getName().equals(Net.VCC_NET))
                                            continue;
                                        int init_index = 0;
                                        boolean valid_index = true;
                                        for (int j = 0; j < 6; j++) {
                                            if ((i & (1 << j)) == 0)
                                                continue;
                                            String log = p2l.getOrDefault("A" + Integer.toString(j + 1), "");
                                            if (log.isEmpty())
                                                continue;
                                            if (log.startsWith("RADR")) {
                                                init_index |= (1 << (Integer.parseInt(log.substring(4))));
                                            } else if (log.startsWith("A[")) {
                                                init_index |= (1 << (Integer.parseInt(log.substring(2, 3))));
                                            } else if (!log.startsWith("I") && !log.startsWith("A")) {
                                                valid_index = false;
                                                break;
                                            } else {
                                                init_index |= (1 << (Integer.parseInt(log.substring(1))));
                                            }
                                        }
                                        if (!valid_index)
                                            continue;
                                        if ((long_init & (1L << init_index)) == 0)
                                            continue;
                                        tfeat.add(belName.replaceAll("[56]", "") + ".INIT[" + i + "]");
                                    }
                                }

                            } else if (belName.contains("FF")) {
                                boolean is_latch = false, is_sync = false, srval = false;
                                String clkpin, srpin, cepin;
                                if (c.getType().equals("FDPE")) {
                                    is_latch = false;
                                    is_sync = false;
                                    srval = true;
                                    clkpin = "C";
                                    cepin = "CE";
                                    srpin = "PRE";
                                } else if (c.getType().equals("FDCE")) {
                                    is_latch = false;
                                    is_sync = false;
                                    srval = false;
                                    clkpin = "C";
                                    cepin = "CE";
                                    srpin = "CLR";
                                } else if (c.getType().equals("FDSE")) {
                                    is_latch = false;
                                    is_sync = true;
                                    srval = true;
                                    clkpin = "C";
                                    cepin = "CE";
                                    srpin = "S";
                                } else if (c.getType().equals("FDRE")) {
                                    is_latch = false;
                                    is_sync = true;
                                    srval = false;
                                    clkpin = "C";
                                    cepin = "CE";
                                    srpin = "R";
                                } else if (c.getType().equals("LDPE")) {
                                    is_latch = true;
                                    is_sync = false;
                                    srval = true;
                                    clkpin = "G";
                                    cepin = "GE";
                                    srpin = "PRE";
                                } else if (c.getType().equals("LDCE")) {
                                    is_latch = true;
                                    is_sync = false;
                                    srval = false;
                                    clkpin = "G";
                                    cepin = "GE";
                                    srpin = "CLR";
                                } else {
                                    continue;
                                }
                                String primtype = is_latch ? "LATCH" : "FF";
                                if (c.getProperty("INIT") != null) {
                                    String init = c.getProperty("INIT").getValue();
                                    tfeat.add(belName + "." + primtype + ".INIT." + init.substring(init.length() - 1));
                                }
                                tfeat.add(belName + "." + primtype + ".SRVAL." + (srval ? "1" : "0"));
                                int half = ("EFGH".contains(belName.substring(0, 1))) ? 1 : 0;
                                latch[half] = is_latch;
                                ffsync[half] = is_sync;
                                clkinv[half] = (c.getProperty("IS_" + clkpin + "_INVERTED") != null && c.getProperty("IS_" + clkpin + "_INVERTED").getValue().equals("1'b1"));
                                srinv[half] = (c.getProperty("IS_" + srpin + "_INVERTED") != null && c.getProperty("IS_" + srpin + "_INVERTED").getValue().equals("1'b1"));
                                haveff[half] = true;
                                int two = belName.endsWith("2") ? 1 : 0;
                                srused[half * 2 + two] = (c.getPhysicalPinMapping(srpin) != null);
                                ceused[half * 2 + two] = (c.getPhysicalPinMapping(cepin) != null);

                            } else if (belName.contains("CARRY8")) {
                                if (!c.getType().equals("CARRY8"))
                                    continue;
                                if (c.getProperty("CARRY_TYPE") != null)
                                    tfeat.add("CARRY8.CARRY_TYPE." + c.getProperty("CARRY_TYPE").getValue());
                                String[] pins = {"CI", "DI[0]", "DI[1]", "DI[2]", "DI[3]", "DI[4]", "DI[5]", "DI[6]", "DI[7]", "CI_TOP"};
                                for (String p : pins) {
                                    String phys = c.getPhysicalPinMapping(p);
                                    if (phys != null && (!p.equals("CI") || !phys.equals("CIN"))) {
                                        EDIFPortInst epi = c.getEDIFCellInst().getPortInst(p);
                                        if (epi != null && epi.getNet() != null) {
                                            String pn = p.replace("[", "").replace("]", "");
                                            tfeat.add("CARRY8." + pn + "." + phys);
                                        }
                                    } else if (p.equals("CI") || p.equals("CI_TOP")) {
                                        EDIFPortInst epi = c.getEDIFCellInst().getPortInst(p);
                                        if (epi != null && epi.getNet() != null) {
                                            String netname = epi.getNet().getName();
                                            if (netname.equals("<const0>"))
                                                tfeat.add("CARRY8." + p + ".0");
                                            else if (netname.equals("<const1>"))
                                                tfeat.add("CARRY8." + p + ".1");
                                        }
                                    }
                                }
                            }

                        }
                        for (int i = 0; i < 2; i++) {
                            String half = "ABCDEFGH".substring(4 * i, 4 * (i + 1));
                            if (!haveff[i])
                                continue;
                            String primtype = latch[i] ? "LATCH" : "FF";
                            tfeat.add(half + "FF." + primtype);
                            tfeat.add(half + "FF." + primtype + ".CLKINV." + (clkinv[i] ? "1" : "0"));
                            tfeat.add(half + "FF." + primtype + ".SRINV." + (srinv[i] ? "1" : "0"));
                            if (ffsync[i])
                                tfeat.add(half + "FF." + primtype + ".SYNC");
                            for (int j = 0; j < 2; j++) {
                                if (srused[i * 2 + j])
                                    tfeat.add(half + "FF" + (j == 1 ? "2" : "") + ".SRUSED");
                                if (ceused[i * 2 + j])
                                    tfeat.add(half + "FF" + (j == 1 ? "2" : "") + ".CEUSED");
                            }
                        }
                        for (SitePIP sp : si.getUsedSitePIPs()) {
                            if (sp.getBELName().contains("INV"))
                                continue;
                            if (sp.getBELName().startsWith("OUTMUX") && sp.getInputPinName().equals("D6")) {
                                if (si.getSitePinInst(sp.getOutputPin().getConnectedSitePinName()) == null)
                                    continue;
                            }
                            tfeat.add(sp.getBELName() + "." + sp.getInputPinName());
                        }
                    } else if (si.getSiteTypeEnum() == SiteTypeEnum.BUFCE_LEAF) {
                        String name = site_index_in_tile(si.getTile(), si.getSite());
                        for (Cell c : si.getCells()) {
                            if (c.getType() != null && c.getType().equals("BUFCE_LEAF")) {
                                tfeat.add(name + ".BUFCE_LEAF.IN_USE");
                                if (c.getProperty("CE_TYPE") != null)
                                    tfeat.add(name + ".BUFCE_LEAF.CE_TYPE." + c.getProperty("CE_TYPE").getValue());
                                var all_props = c.getProperties();
                                for (var e : all_props.entrySet()) {
                                    String propname = e.getKey().getName();
                                    if (propname.startsWith("IS_") && propname.endsWith("_INVERTED")) {
                                        String pinname = propname.substring(3, propname.length() - 9);
                                        String v = e.getValue().getValue();
                                        int base_pos = v.indexOf("'b");
                                        if (base_pos != -1)
                                            v = v.substring(base_pos + 2);
                                        if (pinname.equals("I"))
                                            if (is_sink_inverted(si.getSitePinInst("CLK_IN")))
                                                v = (v.equals("1") ? "0" : "1");
                                        tfeat.add(name + ".BUFCE_LEAF." + pinname + "INV." + v);
                                    }
                                }
                            }
                        }
                    }
                }
                FileWriter vf = new FileWriter(f.getAbsolutePath().replace(".dcp", ".features"), false);
                PrintWriter v = new PrintWriter(vf);
                for (Tile t : des.getDevice().getAllTiles()) {
                    TileTypeEnum tt = t.getTileTypeEnum();
                    if (tt == TileTypeEnum.CLEL_L || tt == TileTypeEnum.CLEL_R || tt == TileTypeEnum.CLEM_R || tt == TileTypeEnum.CLEM
                            || tt == TileTypeEnum.INT || tt == TileTypeEnum.INT_INTF_L_IO) {
                        String tname = t.getName() + ":" + tt.toString();
                        if (!pips_by_tile.containsKey(tname) && !sitefeatures_by_tile.containsKey(tname))
                            continue;
                        v.println(".tile " + tname);
                        if (pips_by_tile.containsKey(tname))
                            for (String p : pips_by_tile.get(tname))
                                v.println(p);
                        if (sitefeatures_by_tile.containsKey(tname))
                            for (String sf : sitefeatures_by_tile.get(tname))
                                v.println(sf);
                    }
                }
                vf.close();
            }
        }

    }
}
