#!/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_PIN
    {module_power_defports}
`endif
);

    {module_base_name} (
        {module_signal_ports}
`ifdef SC_USE_PG_PIN
        {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

        if not 'ports' in mdata:
            return

        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]
        if drive_name == 'units':
            pass
        elif drive_name == 'lp_variant':
            if drive_value == 0:
                drive_value = 'lp'
            else:
                drive_value = 'lp'+str(drive_value+1)
        elif drive_name == "minimum":
            assert drive_value is None
            drive_value = "m"
        else:
            raise TypeError("Unknown drive:"+repr(d))

        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:]))
