#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020 The SkyWater PDK Authors.
#
# Use of this source code is governed by the Apache 2.0
# license that can be found in the LICENSE file or at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0


import os
import sys
import json


copyright_header = """\
// Copyright 2020 The Skywater PDK 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
//
//     https://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.
//
// SPDX-License-Identifier: Apache-2.0
"""

include_header = """\
`ifndef VERILOG_MODE_SIMPLE
`ifndef VERILOG_MODE_BLACKBOX
`ifndef VERILOG_MODE_FULL
// No VERILOG_MODE_XXX defined, fallback to VERILOG_MODE_SIMPLE
`define VERILOG_MODE_SIMPLE 1
`endif
`endif
`endif

`ifdef VERILOG_MODE_SIMPLE
`include "{0}.simple.v"
`endif

`ifdef VERILOG_MODE_BLACKBOX
`include "{0}.blackbox.v"
`endif

`ifdef VERILOG_MODE_FULL
`include "{0}.full.v"
`endif
"""

module_header = """\
//# {library_name}: {cell_name} ({drive_value} {drive_name})
//# {description}
module {module_base_name}_{drive_value} (
    {module_signal_defports}
`ifdef SC_USE_PG_PNG
    {module_power_defports}
`endif
);

    {module_base_name} (
        {module_signal_ports}
`ifdef SC_USE_PG_PNG
        {module_power_ports}
`endif
    );

endmodule
"""

def write_verilog(mdata, outfile, drive=None):
    with open(outfile, 'w') as f:
        f.write(copyright_header)
        f.write('\n')
        f.write(include_header.format(mdata['fullname']))
        f.write('\n')
        if not drive:
            return
        drive_name, drive_value = drive

        module_signal_defports = []
        module_signal_ports = []
        for pname, ptype in mdata['ports']['signal']:
            module_signal_defports.append("{} {}, ".format(ptype, pname))
            module_signal_ports.append(pname)

        module_signal_defports = "".join(module_signal_defports)
        assert module_signal_defports.endswith(", "), module_signal_defports
        module_signal_defports = module_signal_defports[:-2]
        module_signal_ports = ", ".join(module_signal_ports)

        module_power_defports = []
        module_power_ports = []
        for pname, ptype in mdata['ports']['power']:
            module_power_defports.append(", {} {}".format('input', pname))
            module_power_ports.append(", {}".format(pname))
        module_power_defports = "".join(module_power_defports)
        module_power_ports = "".join(module_power_ports)

        library_name = "{} {}".format(
            mdata['library']['name'].upper(), mdata['library']['type'])

        f.write(module_header.format(
            module_base_name = mdata['fullname'],
            cell_name = mdata['name'],
            library_name = library_name,
            drive_name = drive_name,
            drive_value = drive_value,
            description = mdata.get('description', ''),
            module_signal_defports = module_signal_defports,
            module_signal_ports = module_signal_ports,
            module_power_defports = module_power_defports,
            module_power_ports = module_power_ports,
        ))

def echo_file(fname):
    with open(fname) as f:
        sys.stdout.write('\n')
        sys.stdout.write('File:')
        sys.stdout.write(fname)
        sys.stdout.write('\n')
        sys.stdout.write('------\n')
        sys.stdout.write(f.read())
        sys.stdout.write('------\n')
        sys.stdout.flush()



def process(cellpath):
    md_json = os.path.join(cellpath, 'metadata.json')
    if not os.path.exists(md_json):
        return
    assert os.path.exists(md_json), md_json
    mdata = json.load(open(md_json))
    drives = mdata.get('drives', [])
    for d in drives:
        assert len(d) == 1, d
        drive_name = list(d.keys())[0]
        drive_value = list(d.values())[0]
        dvfile = os.path.join(cellpath, "{}_{}.v".format(mdata['fullname'], drive_value))
        write_verilog(mdata, dvfile, list(d.items())[0])
        echo_file(dvfile)

    if not drives:
        outfile = os.path.join(cellpath, "{}.v".format(mdata['fullname']))
        write_verilog(mdata, outfile)
        echo_file(outfile)


def main(args):
    for a in args:
        process(a)



if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
