#!/usr/bin/env python3
# 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.

import argparse
import glob
import os
import pprint
import re
import subprocess
import sys
import traceback

from collections import defaultdict
from shutil import copyfile, move
from pathlib import Path

from common import lib_extract_from_path, version_extract_from_path, lib_extract_from_name, get_cell_directory, extract_version_and_lib_from_path, copy_file_to_output
from common import convert_libname, convert_cell_fullname, convert_pinname
from verilog2full import Copyright_header

superdebug = False
debug = True
debug_print = lambda x: print(x) if debug else 0

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

def prepend_copyright(filename):
 with open(filename, 'r+') as f:
    content = f.read()
    content = content.replace(Copyright_header, '')
    f.seek(0, 0)
    f.write(Copyright_header + content)


def _magic_tcl_header(ofile, gdsfile):
    print('#!/bin/env wish',        file=ofile)
    print('drc off',                file=ofile)
    print('gds readonly true',      file=ofile)
    print('gds rescale false',      file=ofile)
    print('tech unlock *',          file=ofile)
    print('cif warning default',    file=ofile)
    print('gds read ' + gdsfile,    file=ofile)


def magic_get_cells(input_gds, input_techfile):
    destdir, gdsfile = os.path.split(input_gds)
    tcl_path = destdir + '/get_cells.tcl'

    # Generate a tcl script for Magic
    with open(tcl_path, 'w') as ofile:
        _magic_tcl_header(ofile, gdsfile)
        print('quit -noprompt', file=ofile)
    return run_magic(destdir, tcl_path, input_techfile)


def magic_rename_cells(input_gds, input_techfile, cell_list):
    destdir, gdsfile = os.path.split(input_gds)
    tcl_path = destdir + '/rename_cells.tcl'

    # Generate a tcl script for Magic
    with open(tcl_path, 'w') as ofile:
        _magic_tcl_header(ofile, gdsfile)

        # Rename the cells
        for src_cell, dst_cell in cell_list:
            escaped_src_cell = '{'+src_cell+'}'
            escaped_dst_cell = '{'+dst_cell+'}'
            print(f'load {escaped_src_cell}', file=ofile)
            if src_cell != dst_cell:
                print(f'cellname rename {escaped_src_cell} {escaped_dst_cell}', file=ofile)
            print(f'save {escaped_dst_cell}', file=ofile)

        print('quit -noprompt', file=ofile)
    return run_magic(destdir, tcl_path, input_techfile)


def magic_split_gds(input_gds, input_techfile, cell_list):
    destdir, gdsfile = os.path.split(input_gds)
    tcl_path = destdir + '/split_gds.tcl'

    # Generate a tcl script for Magic
    with open(tcl_path, 'w') as ofile:
        _magic_tcl_header(ofile, gdsfile)

        # Write out the cells
        for cell in cell_list:
            escaped_cell = '{'+cell+'}'
            print(f'load {escaped_cell}',      file=ofile)
            print(f'gds write {escaped_cell}', file=ofile)
            print(f'lef write {escaped_cell}', file=ofile)
            print(f'save {escaped_cell}',      file=ofile)

        print('quit -noprompt', file=ofile)
    return run_magic(destdir, tcl_path, input_techfile)


FATAL_ERROR = re.compile('Error parsing')
READING_REGEX = re.compile('Reading "([^"]*)".')


def run_magic(destdir, tcl_path, input_techfile):
    mproc = subprocess.run(['magic', '-dnull', '-noconsole',
        '-T', input_techfile, os.path.abspath(tcl_path)],
        stdin = subprocess.DEVNULL,
        stdout = subprocess.PIPE,
        stderr = subprocess.STDOUT,
        cwd = destdir,
        universal_newlines = True)
    assert mproc.stdout

    max_cellname_width = 0
    output_by_cells = [('', [])]
    fatal_errors = []
    for line in mproc.stdout.splitlines():
        if line.startswith('CIF file read warning: Input off lambda grid by 1/2; snapped to grid'):
            continue
        m = FATAL_ERROR.match(line)
        if m:
            fatal_errors.append(line)
        m = READING_REGEX.match(line)
        if m:
            cell_name = m.group(1)
            max_cellname_width = max(max_cellname_width, len(cell_name))
            output_by_cells.append((cell_name, []))
        output_by_cells[-1][-1].append(line)

    for cell, lines in output_by_cells:
        prefix = "magic " + cell.ljust(max_cellname_width) + ':'
        for l in lines:
            is_error = 'rror' in l
            if superdebug or (debug and is_error):
                print(prefix, l)

    assert not mproc.stderr, mproc.stderr

    if fatal_errors:
        msg = 'ERROR:  Magic had fatal errors in output:\n' + "\n".join(fatal_errors)
        raise SystemError(msg)

    if mproc.returncode != 0:
        msg = 'ERROR:  Magic exited with status ' + str(mproc.returncode)
        print(msg)
        raise SystemError(msg)

    return output_by_cells


class Rewriter:

    other_replacements = [
        (re.compile('S8PIR[_-]10R', re.I),
            lambda m: 'SKY130'),
        (re.compile('S8', re.I),
            lambda m: 'SKY130'),
    ]

    def __init__(self, original_path):
        self._cache_libname = None
        self._cache_cellname = {}
        self._cache_string = {}

        self.structures_reset()

        self.old_lib, self.new_lib, self.version = extract_version_and_lib_from_path(original_path)

        self.rewrite_string = self.rewrite_generic_string

    def structures(self):
        return dict(self._structures)

    def structures_usecount(self):
        structs = list(self._structures_instances.items())
        max_count = max(c for n, c in structs)
        structs.sort(key=lambda x: (max_count-x[1], x[1]))
        return structs

    def structures_reset(self):
        self._structures = {}
        self._structures_instances = {}
        self._structures_pins = {}
        self._structure_last = None

    def replacements(self):
        r = []
        r.append((self._cache_libname, self.new_lib))
        r.extend(self._cache_cellname.items())
        r.extend(self._cache_string.items())

        return dict(r)

    def rewrite_library_name(self, s):
        if self._cache_libname is not None:
            assert s == self._cache_libname, (s, self._cache_libname)
        else:
            self._cache_libname = s
        return self.new_lib

    def set_library_name(self, s):
        return

    def _convert_cell(self, old_name, is_real_structure=True):
        if '$$' in old_name:
            old_cellname, number = old_name.split('$$', 1)
            self.rewrite_structure_name(old_cellname, False)

        new_name = convert_cell_fullname(old_name, self.new_lib)
        assert new_name.startswith(self.new_lib), (new_name, self.new_lib)
        assert old_name not in self._cache_cellname, (old_name, self._cache_cellname)
        self._cache_cellname[old_name] = new_name

    def pins(self, s):
        return self._structures_pins[s]

    def rewrite_structure_name(self, s, is_real_structure=True):
        assert (not is_real_structure) or (s in self._structures), s
        if s not in self._cache_cellname:
            self._convert_cell(s, is_real_structure)
        ns = self._cache_cellname[s]
        if is_real_structure:
            assert s in self._structures, repr((s, ns))+'\n'+pprint.pformat(self._structures)
            assert self._structures[s] is None, repr((sn, self._structures[s]))+'\n'+pprint.pformat(self._structures)
        self._structures[s] = ns

        return ns

    def set_structure_name(self, sn):
        assert sn not in self._structures, sn+'\n'+pprint.pformat(self._structures)

        if debug:
            if self._structure_last != None:
                print("Clearing current structure (was", self._structure_last+")")
                print()

        self._structures[sn] = None
        self._structures_instances[sn] = 0
        self._structures_pins[sn] = []
        self._structure_last = sn

        if debug:
            print()
            print("Setting current structure to", self._structure_last)

    def set_instance_struct(self, s):
        assert s in self._structures, (s, self._structures)
        self._structures_instances[s] += 1
        if debug:
            if self._structure_last != None:
                print("Clearing current structure (was", self._structure_last+")")
                print()
        self._structure_last = None

    def rewrite_instance_struct(self, s):
        assert s in self._cache_cellname, (s, self._cache_cellname)
        return self._cache_cellname[s]

    def rewrite_pin_name(self, s):
        assert self._structure_last is not None, s
        pn = convert_pinname(s.upper())
        print(" Rewriting pin on", self._structure_last, "from", repr(s), "to", repr(pn))
        self._structures_pins[self._structure_last].append(pn)
        return pn

    overrides = {
        ('sky130_fd_sc_hvl','scs8ls', 'inv_2'):             'scs8hvl_inv_2',
        ('sky130_fd_sc_hvl','scs8ls', 'inv_4'):             'scs8hvl_inv_4',
        ('sky130_fd_sc_ls', 'scs8ms', 'tapvgndnovpb_1'):    'scs8ls_tapvgndnovpb_1',
        ('sky130_fd_sc_ls', 'scs8lp', 'diode_2'):           'scs8ls_diode_2',
        ('sky130_fd_sc_ls', 'scs8lp', 'tap_2'):             'scs8ls_tap_2',
        ('sky130_fd_sc_ls', 'scs8ms', 'tapvgnd2_1'):        'scs8ls_tapvgnd2_1',
        ('sky130_fd_sc_ls', 'scs8ms', 'tapvgnd_1'):         'scs8ls_tapvgnd_1',
        ('sky130_fd_sc_ls', 'scs8ms', 'tapvpwrvgnd_1'):     'scs8ls_tapvpwrvgnd_1',
        ('sky130_fd_sc_ms', 'scs8ls', 'clkdlyinv3sd1_1'):   'scs8ms_clkdlyinv3sd1_1',
        ('sky130_fd_sc_ms', 'scs8ls', 'clkdlyinv3sd2_1'):   'scs8ms_clkdlyinv3sd2_1',
        ('sky130_fd_sc_ms', 'scs8ls', 'clkdlyinv3sd3_1'):   'scs8ms_clkdlyinv3sd3_1',
        ('sky130_fd_sc_ms', 'scs8ls', 'clkdlyinv5sd1_1'):   'scs8ms_clkdlyinv5sd1_1',
        ('sky130_fd_sc_ms', 'scs8lp', 'dlygate4s15_1'):     'scs8ms_dlygate4s15_1',
        ('sky130_fd_sc_ms', 'scs8ls', 'tap_1'):             'scs8ms_tap_1',
        ('sky130_fd_sc_ms', 'scs8lp', 'tap_2'):             'scs8ms_tap_2',
    }

    def rewrite_generic_string(self, old_str):
        if old_str in self._cache_string:
            return self._cache_string[old_str]

        # Is this a simple cell name string?
        if old_str in self._cache_cellname:
            cell_fullname = self._cache_cellname[old_str]
            lib_name, cell_name = cell_fullname.split('__', 1)
            print("Rewriting string (cell name) from", repr(old_str), "to", repr(cell_name))
            return cell_name

        # Check this isn't for a different library....
        ext_libname, ext_cellname = lib_extract_from_name(old_str)
        okey = (self.new_lib, ext_libname, ext_cellname)
        if okey in self.overrides:
            override = self.overrides[okey]
            print('Overriding {} with {}'.format(old_str, override))
            return self.rewrite_generic_string(override)
        elif (self.new_lib, ext_libname) == ('sky130_fd_sc_hdll', 'scs8hd'):
            override = 'scs8hdll_'+ext_cellname
            print('Overriding {} with {}'.format(old_str, override))
            return self.rewrite_generic_string(override)
        else:
            assert ext_libname is None or ext_libname == self.old_lib, (
                old_str, ext_libname, ext_cellname, self.old_lib)

        # Does this string contain a cell name?
        new_str = old_str
        for old_cellname, new_cellname in self._cache_cellname.items():
            if old_cellname in new_str:
                new_str = new_str.replace(old_cellname, new_cellname)

        # Does this contain other things needed to replaced?
        for regex, rep in self.other_replacements:
            new_str = regex.sub(rep, new_str)

        self._cache_string[old_str] = new_str
        print("Rewriting string from", repr(old_str), "to", repr(new_str))
        return new_str

    def set_string_type(self, i):
        if i == 5:
            if superdebug:
                print("Next string is a pin name on", self._structure_last)
            self.rewrite_string = self.rewrite_pin_name
        else:
            if superdebug:
                print("Next string is a generic string")
            self.rewrite_string = self.rewrite_generic_string



def replace_gds_strings(gds_filename, call_rewrite_on_rtypes, rewriter):
    source = gds_filename
    dest = gds_filename

    sourcedir, gdsinfile = os.path.split(source)
    destdir, gdsoutfile = os.path.split(dest)

    with open(source, 'rb') as ifile:
        gdsdata = bytearray(ifile.read())

    # If we are rewriting the structure names, we need to rewrite the instances
    # which point to the structure.
    if 'structure_name' in call_rewrite_on_rtypes:
        call_rewrite_on_rtypes.append('instance_struct')

    rtype_mapping = {
        2:  'library_name',   # libname
        6:  'structure_name', # strname - Structure Definition Name
        18: 'instance_struct',# sname - Instance's structure
        22: 'string_type',    # Indicates what the next string is in reference too..
        25: 'string',         # string
    }
    rtype_rmapping = {v:k for k,v in rtype_mapping.items()}

    call_set_on_rtype = ['structure_name', 'instance_struct', 'string_type']

    for r in call_rewrite_on_rtypes:
        assert r in rtype_rmapping, r

    datalen = len(gdsdata)
    if superdebug:
        print('Original data length = ' + str(datalen))
    dataptr = 0
    while dataptr < datalen:
        # Read stream records up to any string, then search for search text.
        bheader = gdsdata[dataptr:dataptr + 2]
        reclen = int.from_bytes(bheader, 'big')
        newlen = reclen

        # The GDS files seem to occasionally end up with trailing zero bytes.
        if newlen == 0:
            if debug:
                print("{:10d} (of {:10d} - {:10d} left)".format(dataptr, datalen, datalen-dataptr), 'Found zero-length record at position in', source)
            if superdebug:
                print('Remaining data', repr(gdsdata[dataptr:]))
            for i in range(dataptr, datalen):
                if gdsdata[i] != 0:
                    raise SystemError('Found non-zero pad byte at {} ({}): {}'.format(i, hex(i), repr(gdsdata[i])))
            break

        rtype = gdsdata[dataptr + 2]
        rtype_name = rtype_mapping.get(rtype, '??? - {}'.format(rtype))
        datatype = gdsdata[dataptr + 3]

        # FIXME: Hack to use different method for pin names...
        if datatype == 2 and rtype_name in call_set_on_rtype:
            assert datatype == 2, (rtype, datatype)
            value = int.from_bytes(gdsdata[dataptr+4:dataptr+6], 'big')
            if superdebug:
                print(
                    "{:10d} (of {:10d} - {:10d} left)".format(dataptr, datalen, datalen-dataptr),
                    'Record type = {:15s} '.format(rtype_name),
                    value,
                )
            getattr(rewriter, 'set_'+rtype_name)(value)

        # Datatype 6 is STRING
        if datatype == 6:
            bstring = gdsdata[dataptr + 4: dataptr + reclen]

            if bstring[-1] == 0:
                # Was original string padded with null byte?  If so,
                # remove the null byte.
                decoded = bstring[:-1].decode('ascii')
            else:
                decoded = bstring.decode('ascii')

            if rtype_name in call_set_on_rtype:
                getattr(rewriter, 'set_'+rtype_name)(decoded)

            if rtype_name in call_rewrite_on_rtypes:
                skipped = False
                repstring = getattr(rewriter, 'rewrite_'+rtype_name)(decoded)
            else:
                skipped = True
                repstring = decoded
            assert repstring is not None

            changed = (decoded != repstring)
            if superdebug:
                print(
                    "{:10d} (of {:10d} - {:10d} left)".format(dataptr, datalen, datalen-dataptr),
                    'Record type = {:15s} '.format(rtype_name),
                    'Skipped = {:5s}'.format(str(skipped)),
                    end="  ",
                )
                if changed:
                    print(repr(decoded), '->', repr(repstring))
                else:
                    print(repr(decoded), '==', repr(repstring))

            brepstring = repstring.encode('ascii')
            newlen = len(brepstring) + 4

            # Record sizes must be even
            if newlen % 2 != 0:
                brepstring += b'\x00'
                newlen += 1

            if changed:
                #before = gdsdata[0:dataptr]
                #after = gdsdata[dataptr + reclen:]

                bnewlen = newlen.to_bytes(2, byteorder='big')
                brtype = rtype.to_bytes(1, byteorder='big')
                bdatatype = datatype.to_bytes(1, byteorder='big')

                # Assemble the new record
                newrecord = bnewlen + brtype + bdatatype + brepstring

                # Reassemble the GDS data around the new record
                #gdsdata = before + newrecord[0:newlen] + after
                gdsdata[dataptr:dataptr+reclen] = newrecord[0:newlen]

                # Adjust the data end location
                datalen += (newlen - reclen)

        # Advance the pointer past the data
        dataptr += newlen

    with open(dest, 'wb') as ofile:
        ofile.write(gdsdata)


def strings_get(pathname):
    string_counts = {}
    lines = subprocess.check_output(
        "strings {} | sort | uniq -c".format(pathname), shell=True).decode('utf-8').splitlines()
    for l in lines:
        c, s = l.strip().split(' ', 1)
        string_counts[s] = int(c)
    return string_counts


def strings_print(h, strings):
    max_len = max(len(s) for s in strings.keys())
    max_count = max(strings.values())
    print()
    print(h)
    print("---")
    for s, c in sorted(strings.items(), key=lambda x: (max_count-x[-1], x[0])):
        print("  ", s.rjust(max_len)+':', c)
    print("---")


def filemain(input_path, temp_dir, techfile, final_dir):
    assert not os.path.exists(temp_dir), temp_dir+" exists!"
    os.makedirs(temp_dir)

    global debug_print

    tmp_gds = temp_dir + '/input.gds'
    copyfile(input_path, tmp_gds)

    rewriter = Rewriter(input_path)

    # First rewrite the cell names
    if debug:
        print()
        print("Rewriting library and structure names")
        print("-------------------------------------")
    replace_gds_strings(tmp_gds, ['library_name', 'structure_name'], rewriter)
    if debug:
        print("-------------------------------------")

    cell_rewrites = list(rewriter.structures().items())
    if not cell_rewrites:
        print("WARNING: No cells found!")
        return

    pprint.pprint(cell_rewrites)

    # Write out the cell list
    with open(temp_dir + '/cells.list', 'w') as f:
        max_len = max(len(s) for s in cell_rewrites)
        for from_str, to_str in sorted(cell_rewrites):
            f.write("  {:s} -> {:s}".format(from_str.rjust(max_len), to_str))
            f.write('\n')

    # Second rewrite any remaining strings.
    # -----
    # The strings could have references to cell names and there is no guarantee
    # that the cell instance definition will appear before a string which
    # happens to contain the name.
    # Hence, we want to know all the cell rewrites before rewriting strings.
    if debug:
        print()
        print("Rewriting strings (inc pin names)")
        print("-------------------------------------")
    rewriter.structures_reset()
    replace_gds_strings(tmp_gds, ['string'], rewriter)
    if debug:
        print("-------------------------------------")

    if debug:
        strings_print("Strings in GDS file:", strings_get(tmp_gds))

    structs = list(rewriter.structures_usecount())
    with open(temp_dir + '/structures.list', 'w') as f:
        f.write("Structures ({} found)\n".format(len(structs)))
        f.write("----------------------\n")
        for name, count in structs:
            f.write("{:10d} {:s}\n".format(count, name))
            for pin in rewriter.pins(name):
                f.write("{:10s}  - {}\n".format('', pin))
            f.write('\n')
    for name, count in structs:
        with open(os.path.join(temp_dir, name+'.gds.pins'), 'w') as f:
            for pin in rewriter.pins(name):
                f.write(pin)
                f.write('\n')
        with open(os.path.join(temp_dir, name+'.lef.pins'), 'w') as f:
            for pin in rewriter.pins(name):
                f.write(pin)
                f.write('\n')

    # Write out the rewrite list
    with open(temp_dir + '/rewrite.list', 'w') as f:
        r = rewriter.replacements()
        max_len = max(len(x) for x in r)
        for from_str, to_str in sorted(r.items()):
            f.write(from_str.rjust(max_len))
            f.write(" -> ")
            f.write(to_str)
            f.write('\n')

    filtered_cells = []
    for name in rewriter.structures():
        if 'libcell' in name:
            continue
        if 'vcells' in name:
            continue
        filtered_cells.append(name)
    filtered_cells.sort()

    # Split apart the GDS file
    output_by_cells = magic_split_gds(tmp_gds, os.path.abspath(techfile), filtered_cells)

    for new_cellname in filtered_cells:
        lef_file = os.path.join(temp_dir, new_cellname+'.lef')
        lef_pin_file = os.path.join(temp_dir, new_cellname+'.lef.pins')
        gds_file = os.path.join(temp_dir, new_cellname+'.gds')
        gds_pin_file = os.path.join(temp_dir, new_cellname+'.gds.pins')
        assert os.path.exists(lef_file), ("Missing lef:", lef_file)
        assert os.path.exists(gds_file), ("Missing gds:", gds_file)

        # LEF file -> output
        prepend_copyright(lef_file)
        final_path = copy_file_to_output(
            lef_file, final_dir, rewriter.new_lib, rewriter.version, new_cellname, okay_exists=True)
        # LEF PINS file -> output
        if final_path:
            copy_file_to_output(
                lef_pin_file, final_dir, rewriter.new_lib, rewriter.version, new_cellname)

        # GDS file -> output
        subprocess.check_call(CHANGE_GDS_DATE+" 1 0 "+gds_file, shell=True)
        copy_file_to_output(
            gds_file, final_dir, rewriter.new_lib, rewriter.version, new_cellname)

        # GDS PINS file -> output
        copy_file_to_output(
            gds_pin_file, final_dir, rewriter.new_lib, rewriter.version, new_cellname)

    return


__dir__ = os.path.dirname(os.path.realpath(__file__))
CHANGE_GDS_DATE = os.path.join(__dir__, 'change_gds_date.py')


def main(args, infile):
    if not os.path.isfile(infile):
        all_input_files = sorted(infile.rglob('*.gds'))
        for f in all_input_files:
            f = str(f)
            main(args, os.path.join(infile, f))
    else:
        infile = str(infile)
        if 'scs8' in infile and 'oa' not in infile:
            print("Skipping", infile)
            return 0
        if 'vcells_drc' in infile:
            print("Skipping", infile)
            return 0
        path = os.path.abspath(infile)
        ver = version_extract_from_path(path)
        if ver is None:
            ver = 'XXXX'
        else:
            ver = "v{}.{}.{}".format(*ver)

        filename = os.path.basename(path)
        tempdir = os.path.join(args.temp, 'gds_split',  filename, ver)
        print()
        print()
        print("Processing", filename, "in", tempdir)
        print('-'*75)
        try:
            filemain(path, tempdir, args.techfile, str(args.output))
        except Exception as e:
            sys.stdout.flush()
            sys.stderr.flush()

            traceback.print_exc(file=sys.stdout)

            # Write error to stdout
            sys.stdout.write('\n')
            sys.stdout.write('\n')
            sys.stdout.write('Error while processing: ')
            sys.stdout.write(infile)
            sys.stdout.write('\n')
            sys.stdout.flush()

            # Write error to stderr too
            sys.stderr.write('\n')
            sys.stderr.write('\n')
            sys.stderr.write('Error while processing: ')
            sys.stderr.write(infile)
            sys.stderr.write('\n')
            sys.stderr.flush()

            raise

        print('-'*75)


if __name__ == "__main__":
    import doctest
    fails, _ = doctest.testmod()
    if fails != 0:
        sys.exit("Some test failed")
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "input",
        help="The path to the source directory/file",
        type=Path)
    parser.add_argument(
        "output",
        help="The path to the output directory",
        type=Path)
    parser.add_argument(
        "techfile",
        help="Full path to the techfile",
        type=str)
    parser.add_argument(
        "temp",
        help="The path to the temp directory",
        type=Path)
    args = parser.parse_args()
    main(args, args.input)
