#
# Copyright (C) 2015 The Android Open Source Project
#
# 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.
#

"""Refreshes a BSP (re-downloads all packages)."""

import argparse

from bsp import manifest
from cli import clicommand
from core import util


class Refresh(clicommand.Command):
    """Refresh an existing BSP.

    Removes and re-downloads all packages for a specified device. Note that this
    does not update a BSP, and is intended to reset in the event that a BSP has
    become somehow messed up. For updating, run:
        bdk bsp update

    The software that you are downloading is the property of the software owner
    and is distributed by the software owner. Google is providing the download
    service as a convenience.
    """

    @staticmethod
    def Args(parser):
        parser.add_argument('device', help='Device to download BSP for.')
        parser.add_argument('-a', '--accept_licenses', action='store_true',
                            help=argparse.SUPPRESS)
        parser.add_argument('-e', '--extract_only', nargs='*',
                            help='List of tarballs to use directly instead of '
                            'downloading from the remote host '
                            'listed in the manifest.')
        parser.add_argument('-l', '--link', action='store_true',
                            help=argparse.SUPPRESS)

    def Run(self, args):
        bsp_manifest = manifest.Manifest.from_json(args.manifest)

        device = bsp_manifest.devices.get(args.device)
        if not device:
            print 'Unrecognized device name:', args.device
            return 1

        extract_only = {}
        if args.extract_only:
            extract_only = self.IdentifyTarballs(args.extract_only, device)
            if len(extract_only) != len(args.extract_only):
                print ('Could not identify all provided tarballs '
                       '(successfully identified {}).').format(
                           extract_only.keys())
                return 1

        os_version = bsp_manifest.operating_systems['brillo'].version
        link_os = os_version if args.link else ''

        print 'Cleaning up...'
        device.uninstall()
        print 'Re-installing...'
        device.install(extract_only, args.accept_licenses, link_os,
                       verbose=True)
        print 'Successfully refreshed {}.'.format(device.full_name)
        return 0

    def IdentifyTarballs(self, tarballs, device):
        """Matches a list of tarballs to their corresponding packages.

        Args:
            tarballs: a list of tarball files.
            device: the device to match to packages in.

        Returns:
            A dictionary mapping { package_name : tarball }.

        Raises:
            bsp.package.VersionError if there is a problem getting any version
            (such as a file not being found).
        """

        mapping = {}
        for tarball in tarballs:
            package_name = device.match_tarball(tarball)
            if package_name:
                mapping[package_name] = tarball

        return mapping
