#!/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, extra = parse_filename_corners(extra)
            print(corners, extra)
        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))
