#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   COPYRIGHT NOTICE STARTS HERE

#   Copyright 2019 © Samsung Electronics Co., Ltd.
#
#   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
#
#       http://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.

#   COPYRIGHT NOTICE ENDS HEREE

import argparse
import subprocess
import logging
import sys
import os
from retrying import retry

import base

log = logging.getLogger(name=__name__)

@retry(stop_max_attempt_number=5, wait_fixed=5000)
def clone_repo(dst, repo, branch=None):
    if branch:
        command = 'git clone -b {} --single-branch https://{} --bare {}'.format(branch, repo, dst)
    else:
        command = 'git clone https://{} --bare {}'.format(repo, dst)
    log.info('Running: {}'.format(command))
    log.info(subprocess.check_output(command.split(), stderr=subprocess.STDOUT).decode())
    log.info('Downloaded: {}'.format(repo))


def download(git_list, dst_dir, progress):
    if not base.check_tool('git'):
        log.error('ERROR: git is not installed')
        progress.finish(dirty=True)
        return 1

    git_set = {tuple(item.split()) for item in base.load_list(git_list)
               if not item.startswith('#')}

    error_count = 0

    base.start_progress(progress, len(git_set), [], log)

    for repo in git_set:
        dst = '{}/{}'.format(dst_dir, repo[0])
        if os.path.isdir(dst):
            log.warning('Directory {} already exists. Repo probably present'.format(dst))
            progress.update(progress.value + 1)
            continue
        try:
            clone_repo(dst, *repo)
            progress.update(progress.value + 1)
        except subprocess.CalledProcessError as err:
            log.error(err.output.decode())
            error_count += 1

    base.finish_progress(progress, error_count, log)
    if error_count > 0:
        log.error('{} were not downloaded. Check logs for details'.format(error_count))
    return error_count


def run_cli():
    parser = argparse.ArgumentParser(description='Download git repositories from list')
    parser.add_argument('git_list', metavar='git-list',
                        help='File with list of npm packages to download.')
    parser.add_argument('--output-dir', '-o', default=os.getcwd(),
                        help='Download destination')

    args = parser.parse_args()

    logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(message)s')

    progress = base.init_progress('git repositories')

    sys.exit(download(args.git_list, args.output_dir, progress))


if __name__ == '__main__':
    run_cli()
