#!/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

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