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

from datetime import datetime
import subprocess
import argparse
import logging
import shutil
import glob
import json
import sys
import os
import hashlib

import tarfile
import git

log = logging.getLogger(__name__)
script_location = os.path.abspath(os.path.join(__file__, '..'))
offline_repository_dir = os.path.abspath(os.path.join(script_location, '..'))


def prepare_application_repository(directory, url, refspec, patch_path):
    """
    Downloads git repository according to refspec, applies patch if provided
    :param directory: path to repository
    :param url: url to repository
    :param refspec: refspec to fetch
    :param patch_path: path git patch to be applied over repository
    :return: repository - git repository object
    """

    try:
        shutil.rmtree(directory)
    except FileNotFoundError:
        pass

    log.info('Cloning {} with refspec {} '.format(url, refspec))
    repository = git.Repo.init(directory)
    origin = repository.create_remote('origin', url)
    origin.pull(refspec)
    repository.git.submodule('update', '--init')

    if patch_path:
        log.info('Applying {} over {} {}'.format(patch_path,
                                                 url,
                                                 refspec))
        repository.git.apply(patch_path)
    else:
        log.info('No patch file provided, skipping patching')

    return repository


def create_package_info_file(output_file, repository_list, tag, metadata):
    """
    Generates text file in json format containing basic information about the build
    :param output_file:
    :param repository_list: list of repositories to be included in package info
    :param tag: build version of packages
    :param metadata: additional metadata into package.info
    :return:
    """
    log.info('Generating package.info file')
    build_info = {
        'Build_info': {
            'build_date': datetime.now().strftime('%Y-%m-%d_%H-%M'),
            'Version': tag,
            'Packages': {}
        }
    }
    for repository in repository_list:
        build_info['Build_info'][
            repository.config_reader().get_value('remote "origin"', 'url')] = repository.head.commit.hexsha

    if metadata:
        for meta in metadata:
            build_info['Build_info'].update(meta)

    with open(output_file, 'w') as outfile:
        json.dump(build_info, outfile, indent=4)


def add_checksum_info(output_dir):
    """
    Add checksum information into package.info file
    :param output_dir: directory where are packages
    """
    tar_files = ['resources_package.tar', 'aux_package.tar', 'sw_package.tar']
    for tar_file in tar_files:
        try:
            checksum = hashlib.md5()
            with open(os.path.join(output_dir, tar_file), 'rb') as f:
                for chunk in iter(lambda: f.read(4096), b""):
                    checksum.update(chunk)
            with open(os.path.join(output_dir, 'package.info'), 'r') as f:
                json_data = json.load(f)
                json_data['Build_info']['Packages'].update({tar_file: checksum.hexdigest()})
            with open(os.path.join(output_dir, 'package.info'), 'w') as f:
                json.dump(json_data, f, indent=4)
        except FileNotFoundError:
            pass


def create_package(tar_content, file_name):
    """
    Creates packages
    :param tar_content: list of dictionaries defining src file and destination tar file
    :param file_name: output file
    """
    log.info('Creating package {}'.format(file_name))
    with tarfile.open(file_name, 'w') as output_tar_file:
        for src, dst in tar_content.items():
            if src != '':
                output_tar_file.add(src, dst)


def metadata_validation(param):
    """
    Validation of metadata parameters
    :param param: parameter to be checked needs to be in format key=value
    """
    try:
        key, value = param.split('=')
        assert (key and value)
        return {key: value}
    except (ValueError, AssertionError):
        msg = "%r is not a valid parameter. Needs to be in format key=value" % param
        raise argparse.ArgumentTypeError(msg)


def build_offline_deliverables(build_version,
                               application_repository_url,
                               application_repository_reference,
                               application_patch_file,
                               application_charts_dir,
                               application_configuration,
                               application_patch_role,
                               output_dir,
                               resources_directory,
                               aux_directory,
                               skip_sw,
                               skip_resources,
                               skip_aux,
                               overwrite,
                               metadata):
    """
    Prepares offline deliverables
    :param build_version: Version for packages tagging
    :param application_repository_url: git repository hosting application helm charts
    :param application_repository_reference: git refspec for repository hosting application helm charts
    :param application_patch_file: git patch file to be applied over application repository
    :param application_charts_dir: path to directory under application repository containing helm charts
    :param application_configuration:  path to application configuration file (helm override configuration)
    :param application_patch_role: path to application patch role (executed just before helm deploy)
    :param output_dir: Destination directory for saving packages
    :param resources_directory: Path to resource directory
    :param aux_directory: Path to aux binary directory
    :param skip_sw: skip sw package generation
    :param skip_resources: skip resources package generation
    :param skip_aux: skip aux package generation
    :param overwrite: overwrite files in output directory
    :param metadata: add metadata info into package.info
    :return:
    """

    if os.path.exists(output_dir) and os.listdir(output_dir):
        if not overwrite:
            log.error('Output directory is not empty, use overwrite to force build')
            raise FileExistsError(output_dir)
        shutil.rmtree(output_dir)

    # Git
    offline_repository = git.Repo(offline_repository_dir)

    application_dir = os.path.join(output_dir, 'application_repository')
    application_repository = prepare_application_repository(application_dir,
                                                            application_repository_url,
                                                            application_repository_reference,
                                                            application_patch_file)

    # Package info
    info_file = os.path.join(output_dir, 'package.info')
    create_package_info_file(info_file, [application_repository, offline_repository], build_version, metadata)

    # packages layout as dictionaries. <file> : <file location under tar archive>
    sw_content = {
        os.path.join(offline_repository_dir, 'ansible'): 'ansible',
        application_configuration: 'ansible/application/application_configuration.yml',
        application_patch_role: 'ansible/application/onap-patch-role',
        os.path.join(application_dir, application_charts_dir): 'ansible/application/helm_charts',
        info_file: 'package.info'
    }
    resources_content = {
        resources_directory: '',
        info_file: 'package.info'
    }
    aux_content = {
        aux_directory: '',
        info_file: 'package.info'
    }

    if not skip_sw:
        log.info('Building offline installer')
        os.chdir(os.path.join(offline_repository_dir, 'ansible', 'docker'))
        installer_build = subprocess.run(
            os.path.join(offline_repository_dir, 'ansible', 'docker', 'build_ansible_image.sh'))
        installer_build.check_returncode()
        os.chdir(script_location)
        sw_package_tar_path = os.path.join(output_dir, 'sw_package.tar')
        create_package(sw_content, sw_package_tar_path)

    if not skip_resources:
        log.info('Building own dns image')
        dns_build = subprocess.run([
            os.path.join(offline_repository_dir, 'build', 'creating_data', 'create_nginx_image', '01create-image.sh'),
            os.path.join(resources_directory, 'offline_data', 'docker_images_infra')])
        dns_build.check_returncode()

        # Workaround for downloading without "flat" option
        log.info('Binaries - workaround')
        download_dir_path = os.path.join(resources_directory, 'downloads')
        os.chdir(download_dir_path)
        for file in os.listdir(download_dir_path):
            if os.path.islink(file):
                os.unlink(file)

        bin_pattern_list = ['**/rke_linux-amd64',
                            '**/helm-*-linux-amd64.tar.gz',
                            '**/kubectl',
                            '**/helm-push_*_linux_amd64.tar.gz',
                            '**/kube-prometheus-stack-*.tgz',
                            '**/cert-manager-*.tgz',
                            '**/cmctl-linux-amd64.tar.gz']

        for pattern in bin_pattern_list:
            for bin_file in glob.glob(os.path.join('.', pattern), recursive=True):
                os.symlink(bin_file, os.path.join(download_dir_path, bin_file.split('/')[-1]))

        os.chdir(script_location)
        # End of workaround

        resources_package_tar_path = os.path.join(output_dir, 'resources_package.tar')
        create_package(resources_content, resources_package_tar_path)

    if not skip_aux:
        aux_package_tar_path = os.path.join(output_dir, 'aux_package.tar')
        create_package(aux_content, aux_package_tar_path)

    add_checksum_info(output_dir)
    shutil.rmtree(application_dir, ignore_errors=True)


def run_cli():
    """
    Run as cli tool
    """
    parser = argparse.ArgumentParser(description='Create Package For Offline Installer')
    parser.add_argument('--build-version',
                        help='version of the build', default='')
    parser.add_argument('application_repository_url', metavar='application-repository-url',
                        help='git repository hosting application helm charts')
    parser.add_argument('--application-repository_reference', default='master',
                        help='git refspec for repository hosting application helm charts')
    parser.add_argument('--application-patch_file',
                        help='git patch file to be applied over application repository', default='')
    parser.add_argument('--application-charts_dir',
                        help='path to directory under application repository containing helm charts ',
                        default='kubernetes')
    parser.add_argument('--application-configuration',
                        help='path to application configuration file (helm override configuration)',
                        default=os.path.join(offline_repository_dir, 'config/application_configuration.yml'))
    parser.add_argument('--application-patch-role',
                        help='path to application patch role file (ansible role) to be executed right before installation',
                        default='')
    parser.add_argument('--output-dir', '-o', default=os.path.join(offline_repository_dir, '../packages'),
                        help='Destination directory for saving packages')
    parser.add_argument('--resources-directory', default=os.path.join(offline_repository_dir, '../resources'),
                        help='Path to resource directory')
    parser.add_argument('--aux-directory',
                        help='Path to aux binary directory', default='')
    parser.add_argument('--skip-sw', action='store_true', default=False,
                        help='Set to skip sw package generation')
    parser.add_argument('--skip-resources', action='store_true', default=False,
                        help='Set to skip resources package generation')
    parser.add_argument('--skip-aux', action='store_true', default=False,
                        help='Set to skip aux package generation')
    parser.add_argument('--overwrite', action='store_true', default=False,
                        help='overwrite files in output directory')
    parser.add_argument('--debug', action='store_true', default=False,
                        help='Turn on debug output')
    parser.add_argument('--add-metadata', nargs="+", type=metadata_validation,
                        help='additional metadata added into package.info, format: key=value')
    args = parser.parse_args()

    if args.debug:
        logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
    else:
        logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(message)s')

    build_offline_deliverables(args.build_version,
                               args.application_repository_url,
                               args.application_repository_reference,
                               args.application_patch_file,
                               args.application_charts_dir,
                               args.application_configuration,
                               args.application_patch_role,
                               args.output_dir,
                               args.resources_directory,
                               args.aux_directory,
                               args.skip_sw,
                               args.skip_resources,
                               args.skip_aux,
                               args.overwrite,
                               args.add_metadata)


if __name__ == '__main__':
    run_cli()
