#! /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 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()
