#!/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 os
import json
import argparse
from pathlib import Path
import common

common_prefix="skywater-pdk/libraries"

def replace_versions(json, use_key):
    if type(json) == list:
        return [replace_versions(item, use_key) for item in json]

    if type(json) == dict:
        if use_key:
            return { replace_versions(key, use_key) : value
                         for key, value in json.items() }
        else:
            return { key : replace_versions(value, use_key)
                         for key, value in json.items() }

    v = common.version_extract_from_path(json)
    if v is None:
        return json
    old_version = f"V{v[0]}.{v[1]}.{v[2]}"
    new_version = f"v0.{v[0] * 10 + v[1]}.{v[2]}"
    json = json.replace(old_version, new_version)
    return json



if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "output",
        help="The path to the output directory",
        type=Path)

    parser.add_argument(
        "tmp",
        help="The path to the temporary directory",
        type=Path)

    args = parser.parse_args()

    libraries = args.output / common_prefix
    for library in libraries.iterdir():
        if not library.is_dir():
            continue
        any_versions = False
        versions = []
        for version_path in library.iterdir():
            if not version_path.is_dir():
                continue
            version = common.version_extract_from_path(str(version_path))
            if version is None:
                continue
            any_versions = True

            new_path = version_path.parent / f"v0.{version[0] * 10 + version[1]}.{version[2]}"
            new_version = common.version_extract_from_path(str(new_path))

            print(f"Renaming version from {version_path} to {new_path}")
            version_path.replace(new_path)

            versions.append(new_version)

        if any_versions:
            versions.sort(reverse=True)
            v = versions[0]
            highest = f"v{v[0]}.{v[1]}.{v[2]}"
            os.system(f"cd {library}; ln -fs {highest} latest")

    for mapping in args.tmp.glob('*.filemapping.json'):
        print(f"Updating {mapping} to reflect version changes")
        map_json = json.load(open(mapping))
        map_json = replace_versions(map_json, False)
        if "reverse-" in mapping.name:
            map_json = replace_versions(map_json, True)

        with open(mapping, 'w') as srctodst:
            json.dump(map_json, srctodst, indent=2)



