#!/usr/bin/env python

#
# Copyright (c) 2019-2020,2022 Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# 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
#
# 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 json
import os
import subprocess
import sys

def print_args(args, **kwargs):
    cwd = kwargs['cwd']

    if isinstance(args, list):
        args = ' '.join(args)

    print('%s$ %s' % (cwd, args))

def check_call(args, **kwargs):
    print_args(args, **kwargs)
    return subprocess.check_call(args, **kwargs)

def check_output(args, **kwargs):
    print_args(args, **kwargs)
    return subprocess.check_output(args, **kwargs)

###############################################################################
# Git class
###############################################################################

class Git(object):
    def __init__(self, pwd, path, name, fetchurl, pushurl=None, revision='origin/master'):
        self.pwd = pwd
        self.path = path
        self.name = name
        self.absolutepath = os.path.join(pwd, path)
        self.fetchurl = fetchurl
        self.pushurl = pushurl
        self.revision = revision

    def checkout_and_update(self):
        self.init()
        self.remote_add(self.name, self.revision, self.fetchurl, self.pushurl)
        self.fetch(self.name)
        self.checkout(self.name, self.revision)

    def init(self):
        if not os.path.exists(self.absolutepath):
            os.makedirs(self.absolutepath)

        if not os.path.exists(os.path.join(self.absolutepath, '.git')):
            check_output(['git', 'init'], cwd=self.absolutepath)

    def remote_add(self, name, revision, fetchurl, pushurl):
        remotes = self.__get_remotes()

        if name in remotes:
            if fetchurl != remotes[name]['fetch']:
                raise Exception("Fetch url '%s' from repository for remote '%s' does not match fetch url '%s' from manifest." % (fetchurl, name, remotes[name]['fetch']))

            if pushurl not in (None, remotes[name]['push']):
                raise Exception("Push url '%s' from repository for remote '%s' does not match push url '%s' from manifest." % (pushurl, name, remotes[name]['push']))
        else:
            check_output(['git', 'remote', 'add', '-m', revision, name, fetchurl], cwd=self.absolutepath)

            if pushurl:
                check_output(['git', 'remote', 'set-url', '--add', '--push', name, pushurl], cwd=self.absolutepath)

    def fetch(self, name):
        check_output(['git', 'fetch', name], cwd=self.absolutepath)

    def checkout(self, name, revision):
        rev = self.__get_rev(name, revision)
        check_output(['git', 'checkout', rev], stderr=subprocess.STDOUT, cwd=self.absolutepath)

    def get_dict(self, sha1):
        data = {}
        data['path'] = self.path
        data['name'] = self.name
        data['fetchurl'] = self.fetchurl

        if self.pushurl:
            data['pushurl'] = self.pushurl

        if sha1:
            data['revision'] = self.__get_rev(self.name, self.revision)
        else:
            data['revision'] = self.revision

        return data

    def __get_rev(self, name, revision):
        try:
            rev = check_output(['git', 'rev-parse', name + '/' + revision], stderr=subprocess.STDOUT, cwd=self.absolutepath)
        except:
            rev = check_output(['git', 'rev-parse', revision], cwd=self.absolutepath)

        return rev.decode('utf-8').strip()

    def __get_remotes(self):
        remotes = {}
        for remote in check_output(['git', 'remote'], cwd=self.absolutepath).decode('utf-8').strip().split('\n'):
            fetch = check_output(['git', 'remote', 'get-url', remote], cwd=self.absolutepath).decode('utf-8').strip()
            push = check_output(['git', 'remote', 'get-url', '--push', remote], cwd=self.absolutepath).decode('utf-8').strip()
            remotes[remote] = { 'fetch': fetch, 'push': push }

        return remotes

###############################################################################
# Externals class
###############################################################################

class Externals:
    def __init__(self, config):
        self.externals = []
        self.load_config(config)

    def load_config(self, config):
        self.pwd = os.path.dirname(os.path.realpath(config))

        with open(config, 'r') as fp:
            data = json.load(fp)

        for ext in data['externals']:
            git = Git(self.pwd, ext['path'], ext.get('name', 'origin'), ext['fetchurl'], ext.get('pushurl', None), ext['revision'])
            self.externals.append(git)

    def fetch(self):
        for ext in self.externals:
            ext.checkout_and_update()

    def get_dict(self, sha1):
        data = { 'externals': [] }
        for ext in self.externals:
            data['externals'].append(ext.get_dict(sha1))

        return data

    def dump(self, fhandle, sha1):
        fhandle.write(json.dumps(self.get_dict(sha1), sort_keys=False, separators=(',', ': '), indent=4))

###############################################################################
# Handle functions
###############################################################################

def handle_fetch(args):
    externals = Externals(args.configuration)
    externals.fetch()

def handle_dump(args):
    externals = Externals(args.configuration)
    externals.dump(sys.stdout, args.sha1)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Fetch external repositories.')
    parser.add_argument('-c', '--configuration', default='externals.json', help='Externals configuration file')
    subparsers = parser.add_subparsers()

    subparser = subparsers.add_parser('fetch', description='Fetch external repositories.')
    subparser.set_defaults(func=handle_fetch)

    subparser = subparsers.add_parser('dump', description='Dump configuration.')
    subparser.set_defaults(func=handle_dump)
    subparser.add_argument('-s', '--sha1', action='store_true', help='Replace revision with current SHA-1')

    args = parser.parse_args()

    if 'func' not in args:
        parser.print_help()
        sys.exit(2)

    sys.exit(args.func(args))

