#!/usr/bin/env python3
# # -*- coding: utf-8 -*-
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Create tarballs with modem FW, and upload them to Chromium OS Archive
Mirrors.
"""

import argparse
import logging
from distutils.dir_util import copy_tree
from enum import Enum
import os
import shutil
import sys
import tempfile


class PackageType(Enum):
    """Packaging options for different firmwares or cust packs."""

    L850_MAIN_FW = 'l850-main-fw'
    L850_OEM_FW = 'l850-oem-fw'
    L850_OEM_DIR_ONLY = 'l850-oem-dir'
    NL668_MAIN_FW = 'nl668-main-fw'

    def __str__(self):
        return self.value


MIRROR_PATH = 'gs://chromeos-localmirror/distfiles/'
FIBOCOM_TARBALL_PREFIX = 'cellular-firmware-fibocom-'
L850_TARBALL_PREFIX = FIBOCOM_TARBALL_PREFIX + 'l850-'
NL668_TARBALL_PREFIX = FIBOCOM_TARBALL_PREFIX + 'nl668-'

OEM_FW_PREFIX = 'OEM_cust.'
OEM_FW_POSTFIX = '_signed.fls3.xz'


class FwUploader(object):
    """Class to verify the files and upload the tarball to a gs bucket."""

    def __init__(self, path, upload, tarball_dir_name):
        self.path = os.path.abspath(path)
        self.upload = upload
        self.basename = os.path.basename(self.path)
        self.tarball_dir_name = tarball_dir_name

    def process_fw_and_upload(self):
        if not self.validate():
            return os.EX_USAGE

        tempdir = tempfile.mkdtemp()
        path_to_package = os.path.join(tempdir, self.tarball_dir_name)
        os.mkdir(path_to_package)

        if not self.prepare_files(self.path, path_to_package):
            logging.error('Failed to prepare files for packaging')
            return os.EX_OSFILE

        os.chdir(tempdir)
        tarball_name = '{0}.tar.xz'.format(self.tarball_dir_name)
        os.system('tar -Ipixz -cf {0} {1}/'.format(tarball_name,
                                                   self.tarball_dir_name))
        tarball_path = os.path.join(tempdir, tarball_name)
        logging.info('Tarball created: %s', tarball_path)
        if self.upload:
            gs_bucket_path = os.path.join(MIRROR_PATH, tarball_name)
            logging.info('Uploading file %s to %s', tarball_path,
                         gs_bucket_path)
            os.system('gsutil cp -n -a public-read {0} {1}'.format(
                tarball_path, gs_bucket_path))

        logging.info('Removing temporary files')
        shutil.rmtree(tempdir)
        return os.EX_OK


class L850MainFw(FwUploader):
    """Uploader class for L850GL main FW."""

    def __init__(self, path, upload):
        super().__init__(path, upload, None)
        self.tarball_dir_name = L850_TARBALL_PREFIX + self.basename.replace(
            '.fls3.xz', '')

    def validate(self):
        main_fw_postfix = 'Secureboot.fls3.xz'
        if not self.path.endswith(main_fw_postfix):
            logging.error('The main FW file `%s` name does not match `*%s`',
                          self.path, main_fw_postfix)
            return False
        return True

    @staticmethod
    def prepare_files(fw_path, target_path):
        logging.info('Copying %s into %s', fw_path, target_path)
        shutil.copy(fw_path, target_path)
        return True


class L850OemFw(FwUploader):
    """Uploader class for L850GL OEM FW."""

    def __init__(self, path, upload):
        super().__init__(path, upload, None)
        self.tarball_dir_name = '{0}{1}'.format(
            L850_TARBALL_PREFIX, self.basename.replace(OEM_FW_POSTFIX, ''))


    def validate(self):
        if not (self.basename.startswith(OEM_FW_PREFIX)
                and self.basename.endswith(OEM_FW_POSTFIX)):
            logging.error('The OEM FW file `%s` name does not match `%s*%s`',
                          self.basename, OEM_FW_PREFIX, OEM_FW_POSTFIX)
            return False
        return True

    @staticmethod
    def prepare_files(fw_path, target_path):
        logging.info('Copying %s into %s', fw_path, target_path)
        shutil.copy(fw_path, target_path)
        return True


class L850OemDir(FwUploader):
    """Uploader class for L850GL cust packs directory."""

    def __init__(self, path, upload, revision, board):
        super().__init__(path, upload, None)
        self.tarball_dir_name = '{0}{1}-carriers_OEM_{2}-{3}'.format(
            L850_TARBALL_PREFIX, board, self.basename, revision)
        self.revision = revision

    def validate(self):
        if not self.revision.startswith(
                'r') or not self.revision[1:].isdigit():
            logging.error('The revision should be in the form of r##')
            return False
        if len(self.basename) != 4 or not self.basename.isdigit():
            logging.error('The OEM carrier directory name is expected to '
                          'consist of 4 digits')
            return False
        return True

    def prepare_files(self, dir_path, target_path):
        logging.info('Copying %s into %s', dir_path, target_path)
        os.mkdir(os.path.join(target_path, self.basename))
        copy_tree(dir_path, os.path.join(target_path, self.basename))

        return True


class NL668MainFw(FwUploader):
    """Uploader class for NL668 main FW."""

    def __init__(self, path, upload):
        super().__init__(path, upload, None)
        self.tarball_dir_name = NL668_TARBALL_PREFIX + self.basename

    def validate(self):
        if not os.path.isdir(self.path):
            logging.error('The NL668 FW should be a directory')
            return False
        return True

    def prepare_files(self, dir_path, target_path):
        logging.info('Copying %s into %s', dir_path, target_path)
        os.mkdir(os.path.join(target_path, self.basename))
        copy_tree(dir_path, os.path.join(target_path, self.basename))
        return True


def parse_arguments(argv):
    """Parses command line arguments.

    Args:
        argv: List of commandline arguments.

    Returns:
        Namespace object containing parsed arguments.
    """

    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument('type',
                        type=PackageType,
                        choices=list(PackageType),
                        help='The type of package to create')

    parser.add_argument(
        'path', help='The path to the FW file or directory to be packaged.')

    parser.add_argument(
        '--board',
        help='The ChromeOS board in which this cust pack will be used.')

    parser.add_argument(
        '--revision',
        help='The next ebuild number for that board. If the current ebuild '
        'revision is r12, enter r13.')

    parser.add_argument('--upload',
                        default=False,
                        action='store_true',
                        help='upload file to GS bucket.')

    return parser.parse_args(argv[1:])


def main(argv):
    """Main function."""

    logging.basicConfig(level=logging.DEBUG)
    opts = parse_arguments(argv)
    if opts.type == PackageType.L850_MAIN_FW:
        fw_uploader = L850MainFw(opts.path, opts.upload)
    elif opts.type == PackageType.L850_OEM_FW:
        fw_uploader = L850OemFw(opts.path, opts.upload)
    elif opts.type == PackageType.L850_OEM_DIR_ONLY:
        if not opts.revision:
            logging.error('The ebuild revision is needed to pack it, since '
                          'the tarballs need to be unique.')
            return os.EX_USAGE
        if not opts.board:
            logging.error('Please enter the board name.')
            return os.EX_USAGE
        fw_uploader = L850OemDir(opts.path, opts.upload, opts.revision,
                                 opts.board)
    elif opts.type == PackageType.NL668_MAIN_FW:
        fw_uploader = NL668MainFw(opts.path, opts.upload)

    return fw_uploader.process_fw_and_upload()


if __name__ == '__main__':
    sys.exit(main(sys.argv))
