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

from .base import parse_filename as parse_filename_base
from .corners import parse_filename as parse_filename_corners


def analyze(pathname):
    if pathname.endswith('README.rst'):
        return

    sys.stdout.flush()
    sys.stderr.flush()
    print()
    print(pathname)

    try:
        obj, extra, extension = parse_filename_base(pathname)
        print(extension)
        print(obj)
    except Exception as e:
        traceback.print_exc()
        return

    sys.stdout.flush()

    if not extra:
        return

    if extension in ('wrap.lib', 'wrap.json', 'cell.lib', 'cell.json'):
        try:
            corners = parse_filename_corners(extra)
            print(corners)
        except Exception as e:
            traceback.print_exc()
            return


def main(argv):
    for a in argv[1:]:
        if os.path.isdir(a):
            for root, dirs, files in os.walk(a):
                dirs.sort()
                files.sort()
                for f in files:
                    pathname = os.path.join(a, root, f)
                    analyze(pathname)
        elif os.path.isfile(a):
            analyze(a)


if __name__ == "__main__":
    import sys
    sys.exit(main(sys.argv))
