// 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.Cell;
import com.xilinx.rapidwright.design.Design;
import com.xilinx.rapidwright.design.Net;
import com.xilinx.rapidwright.design.SiteInst;
import com.xilinx.rapidwright.device.*;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;

public class dump_laguna {

    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);
    }

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


        File folder = new File("specimen_lag");
        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<>();
                HashSet<Node> usednodes = new HashSet<>();
                for (Net n : des.getNets()) {
                    HashMap<Node, PIP> uphill = new HashMap<>();

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

                        usednodes.add(p.getStartNode());
                        usednodes.add(p.getEndNode());
                    }
                    for (PIP p : n.getPIPs()) {

                        String tile = p.getTile().getName() + ":" + p.getTile().getTileTypeEnum().toString();
                        if (p.getTile().getTileTypeEnum() == TileTypeEnum.BRAM || p.getTile().getTileTypeEnum() == TileTypeEnum.INT)
                            continue;
                        if (!pips_by_tile.containsKey(tile))
                            pips_by_tile.put(tile, new ArrayList<>());
                        if (p.isBidirectional()) {
                            Node cursor = p.getStartNode();
                            boolean is_fwd = false;
                            if (uphill.containsKey(p.getStartNode())) {
                                is_fwd = true;
                                uphill.put(p.getEndNode(), p);
                            } else if (uphill.containsKey(p.getEndNode())) {
                                is_fwd = false;
                                uphill.put(p.getStartNode(), p);
                            } else {
                                continue;
                            }
                            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());
                            SitePin sp = p.getEndNode().getSitePin();
                            if (sp != null && p.isRouteThru() && sp.getSite().getSiteTypeEnum() == SiteTypeEnum.LAGUNA && sp.getPinName().startsWith("RXQ")) {
                                String prefix = site_index_in_tile(p.getTile(), sp.getSite());
                                String pin = sp.getPinName();
                                pips_by_tile.get(tile).add(prefix + ".RX_REG" + pin.charAt(pin.length()-1) + ".BYPASS");
                            }
                        }
                    }
                }

                for (Tile t : des.getDevice().getAllTiles()) {
                    if (t.getTileTypeEnum() == TileTypeEnum.LAG_LAG) {
                        String tile = t.getName() + ":" + t.getTileTypeEnum().toString();
                        if (!sitefeatures_by_tile.containsKey(tile))
                            sitefeatures_by_tile.put(tile, new ArrayList<>());
                        ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
                        for (Site s : t.getSites()) {
                            if (s.getSiteTypeEnum() != SiteTypeEnum.LAGUNA)
                                continue;
                            boolean[] no_rx_used = {true, true, true, true, true, true};
                            SiteInst si = des.getSiteInstFromSite(s);
                            if (si != null) {
                                for (BEL b : si.getBELs()) {
                                    if (!b.getName().startsWith("RX_REG"))
                                        continue;
                                    if (si.getCell(b) != null && si.getCell(b).getType() != null && !si.getCell(b).getType().equals("<LOCKED>")) {
                                        String qw = si.getCell(b).getSiteWireNameFromLogicalPin("Q");
                                        if (qw != null && si.getNetFromSiteWire(qw) != null && !si.getNetFromSiteWire(qw).getSinkPins().isEmpty())
                                            no_rx_used[Integer.parseInt(b.getName().substring(6))] = false;
                                    }
                                }
                            }
                            String prefix = site_index_in_tile(t, s);
                            for (int i = 0; i < 6; i++)
                                if (no_rx_used[i])
                                    tfeat.add(prefix + ".RX_REG" + i + ".BYPASS");

                        }
                    }
                }
                for (SiteInst si : des.getSiteInsts()) {
                    if (si.getSiteTypeEnum() != SiteTypeEnum.LAGUNA)
                        continue;
                    String prefix = site_index_in_tile(si.getTile(), si.getSite());
                    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);
                    for (BEL b : si.getBELs()) {
                        Cell c = si.getCell(b);
                        if (c != null && c.getType() != null && !c.getType().equals("<LOCKED>")) {
                            boolean is_latch = false, is_sync = false, srval = false;
                            String clkpin, srpin, cepin;
                            if (c.getType().equals("FDPE")) {
                                is_sync = false;
                                srval = true;
                                clkpin = "C";
                                cepin = "CE";
                                srpin = "PRE";
                            } else if (c.getType().equals("FDCE")) {
                                is_sync = false;
                                srval = false;
                                clkpin = "C";
                                cepin = "CE";
                                srpin = "CLR";
                            } else if (c.getType().equals("FDSE")) {
                                is_sync = true;
                                srval = true;
                                clkpin = "C";
                                cepin = "CE";
                                srpin = "S";
                            } else if (c.getType().equals("FDRE")) {
                                is_sync = true;
                                srval = false;
                                clkpin = "C";
                                cepin = "CE";
                                srpin = "R";
                            } else {
                                continue;
                            }
                            String group = b.getName().substring(0, 6);
                            tfeat.add(prefix + "." + group + ".USED");
                            if (is_sync)
                                tfeat.add(prefix + "." + group + ".SYNC");
                            else
                                tfeat.add(prefix + "." + group + ".ASYNC");
                            tfeat.add(prefix + "." + b.getName() + ".SRVAL." + (srval ? "1" : "0"));
                            if (c.getProperty("INIT") != null) {
                                String init = c.getProperty("INIT").getValue();
                                tfeat.add(prefix + "." + b.getName() + ".INIT." + init.substring(init.length() - 1));
                            }
                            String clk = c.getSiteWireNameFromLogicalPin(clkpin);
                            if (clk != null && si.getNetFromSiteWire(clk) != null && !si.getNetFromSiteWire(clk).isStaticNet()) {
                                if (c.getProperty("IS_C_INVERTED") != null) {
                                    String init = c.getProperty("IS_C_INVERTED").getValue();
                                    tfeat.add(prefix + "." + group + ".CLKINV." + init.substring(init.length() - 1));
                                }
                            }
                            String srw = c.getSiteWireNameFromLogicalPin(srpin);
                            if (srw != null && si.getNetFromSiteWire(srw) != null && !si.getNetFromSiteWire(srw).isStaticNet()) {
                                if (c.getProperty("IS_" + srpin + "_INVERTED") != null) {
                                    String init = c.getProperty("IS_" + srpin + "_INVERTED").getValue();
                                    tfeat.add(prefix + "." + group + ".SRINV." + init.substring(init.length() - 1));
                                }
                                tfeat.add(prefix + "." + group + ".SRUSED");
                            }
                            String cew = c.getSiteWireNameFromLogicalPin(cepin);
                            if (cew != null && si.getNetFromSiteWire(srw) != null && !si.getNetFromSiteWire(srw).isStaticNet()) {
                                tfeat.add(prefix + "." + group + ".CEUSED");
                            }
                        }
                    }
                }
                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.LAG_LAG) {
                        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();
            }

        }

    }
}
