#! /usr/bin/env python3
# -*- 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 HERE

import argparse
import datetime
import logging
import os
import shutil
import subprocess
import sys
import timeit

from command_downloader import CommandDownloader

log = logging.getLogger(name=__name__)


class GitDownloader(CommandDownloader):
    def __init__(self, *list_args):
        super().__init__('git repositories', 'git', *list_args)

    @property
    def check_table(self):
        """
        Table with information which items from lists are downloaded
        """
        self.missing()
        header = ['Name', 'Branch', 'Downloaded']
        return self._check_table(header, {'Name': 'l'},
                                 ((*item.split(), self._downloaded(item)) for item
                                  in self._data_list))

    @staticmethod
    def _download_item(item):
        repo, branch = item[0].split()
        dst = '{}/{}'.format(item[1], repo)
        command = 'git clone -b {} --single-branch https://{} --bare {}'.format(branch,
                                                                                repo,
                                                                                dst)
        if os.path.exists(dst):
            log.warning('File or directory exists {} removing and cloning'
                        ' to be sure it is latest.'.format(dst))
            if os.path.isfile(dst):
                os.remove(dst)
            elif os.path.isdir(dst):
                shutil.rmtree(dst)

        log.info('Running: {}'.format(command))
        log.info(
            subprocess.check_output(command.split(), stderr=subprocess.STDOUT).decode())
        log.info('Downloaded: {}'.format(repo))

    def _is_missing(self, item):
        """
        Check if item is missing (not cloned)
        :param item: item to check
        :return: True if not present 'maybe' if directory exists
        """
        dst = '{}/{}'.format(self._data_list[item], item.split()[0])
        if os.path.exists(dst):
            # it is bare repo who knows
            return 'maybe'
        return True

    def _downloaded(self, item):
        """
        Check if item is present (cloned)
        :param item: item to check
        :return: True if not cloned 'maybe' if directory exists
        """
        missing = self._is_missing(item)
        if missing != 'maybe':
            return False
        # It is bare repo so who knows if it is latest version
        return 'maybe'

    def missing(self):
        """
        Check for missing data (not downloaded)
        :return: dictionary of missing items
        """
        self._missing = {item: dst for item, dst in self._data_list.items()}
        return self._missing


def run_cli():
    """
    Run as cli tool
    """
    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')
    parser.add_argument('--check', '-c', action='store_true', default=False,
                        help='Check mode')

    args = parser.parse_args()

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

    downloader = GitDownloader([args.git_list, args.output_dir])
    if args.check:
        log.info('Check mode. No download will be executed.')
        log.info(downloader.check_table)
        sys.exit(0)

    timer_start = timeit.default_timer()
    try:
        downloader.download()
    except RuntimeError:
        sys.exit(1)
    finally:
        log.info('Downloading finished in {}'.format(
            datetime.timedelta(seconds=timeit.default_timer() - timer_start)))


if __name__ == '__main__':
    run_cli()
