#!/usr/bin/env python
#
# Copyright 2018 - 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.
r"""RemoteImageLocalInstance class.

Create class that is responsible for creating a local instance AVD with a
remote image.
"""
from __future__ import print_function
import glob
import logging
import os
import subprocess
import sys

from acloud import errors
from acloud.create import local_image_local_instance
from acloud.internal import constants
from acloud.internal.lib import android_build_client
from acloud.internal.lib import auth
from acloud.internal.lib import utils
from acloud.setup import setup_common

# Download remote image variables.
_CVD_HOST_PACKAGE = "cvd-host_package.tar.gz"
_CUTTLEFISH_COMMON_BIN_PATH = "/usr/lib/cuttlefish-common/bin/"
_CONFIRM_DOWNLOAD_DIR = ("Download dir %(download_dir)s does not have enough "
                         "space (available space %(available_space)sGB, "
                         "require %(required_space)sGB).\nPlease enter "
                         "alternate path or 'q' to exit: ")
# The downloaded image artifacts will take up ~8G:
#   $du -lh --time $ANDROID_PRODUCT_OUT/aosp_cf_x86_phone-img-eng.XXX.zip
#   422M
# And decompressed becomes 7.2G (as of 11/2018).
# Let's add an extra buffer (~2G) to make sure user has enough disk space
# for the downloaded image artifacts.
_REQUIRED_SPACE = 10
_BOOT_IMAGE = "boot.img"
# TODO(b/129009852):UnpackBootImage and setfacl are deprecated.
UNPACK_BOOTIMG_CMD = "%s -boot_img %s" % (
    os.path.join(_CUTTLEFISH_COMMON_BIN_PATH, "unpack_boot_image.py"),
    "%s -dest %s")
ACL_CMD = "setfacl -m g:libvirt-qemu:rw %s"

logger = logging.getLogger(__name__)


class RemoteImageLocalInstance(local_image_local_instance.LocalImageLocalInstance):
    """Create class for a remote image local instance AVD.

    RemoteImageLocalInstance just defines logic in downloading the remote image
    artifacts and leverages the existing logic to launch a local instance in
    LocalImageLocalInstance.
    """

    def GetImageArtifactsPath(self, avd_spec):
        """Download the image artifacts and return the paths to them.

        Args:
            avd_spec: AVDSpec object that tells us what we're going to create.

        Raises:
            errors.NoCuttlefishCommonInstalled: cuttlefish-common doesn't install.

        Returns:
            Tuple of (local image file, host bins package) paths.
        """
        if not setup_common.PackageInstalled("cuttlefish-common"):
            raise errors.NoCuttlefishCommonInstalled(
                "Package [cuttlefish-common] is not installed!\n"
                "Please run 'acloud setup --host' to install.")

        avd_spec.image_download_dir = self._ConfirmDownloadRemoteImageDir(
            avd_spec.image_download_dir)

        image_dir = self._DownloadAndProcessImageFiles(avd_spec)
        launch_cvd_path = os.path.join(image_dir, "bin",
                                       constants.CMD_LAUNCH_CVD)
        if not os.path.exists(launch_cvd_path):
            raise errors.GetCvdLocalHostPackageError(
                "No launch_cvd found. Please check downloaded artifacts dir: %s"
                % image_dir)
        return image_dir, image_dir

    @utils.TimeExecute(function_description="Downloading Android Build image")
    def _DownloadAndProcessImageFiles(self, avd_spec):
        """Download the CF image artifacts and process them.

        Download from the Android Build system, unpack the boot img file,
        and ACL the image files.

        Args:
            avd_spec: AVDSpec object that tells us what we're going to create.

        Returns:
            extract_path: String, path to image folder.
        """
        cfg = avd_spec.cfg
        build_id = avd_spec.remote_image[constants.BUILD_ID]
        build_target = avd_spec.remote_image[constants.BUILD_TARGET]

        extract_path = os.path.join(
            avd_spec.image_download_dir,
            constants.TEMP_ARTIFACTS_FOLDER,
            build_id)

        logger.debug("Extract path: %s", extract_path)
        # TODO(b/117189191): If extract folder exists, check if the files are
        # already downloaded and skip this step if they are.
        if not os.path.exists(extract_path):
            os.makedirs(extract_path)
            self._DownloadRemoteImage(cfg, build_target, build_id, extract_path)
            self._UnpackBootImage(extract_path)
            self._AclCfImageFiles(extract_path)

        return extract_path

    @staticmethod
    def _DownloadRemoteImage(cfg, build_target, build_id, extract_path):
        """Download cuttlefish package and remote image then extract them.

        Args:
            cfg: An AcloudConfig instance.
            build_target: String, the build target, e.g. cf_x86_phone-userdebug.
            build_id: String, Build id, e.g. "2263051", "P2804227"
            extract_path: String, a path include extracted files.
        """
        remote_image = "%s-img-%s.zip" % (build_target.split('-')[0],
                                          build_id)
        artifacts = [_CVD_HOST_PACKAGE, remote_image]

        build_client = android_build_client.AndroidBuildClient(
            auth.CreateCredentials(cfg))
        for artifact in artifacts:
            temp_filename = os.path.join(extract_path, artifact)
            build_client.DownloadArtifact(
                build_target,
                build_id,
                artifact,
                temp_filename)
            utils.Decompress(temp_filename, extract_path)
            try:
                os.remove(temp_filename)
                logger.debug("Deleted temporary file %s", temp_filename)
            except OSError as e:
                logger.error("Failed to delete temporary file: %s", str(e))

    @staticmethod
    def _UnpackBootImage(extract_path):
        """Unpack Boot.img.

        Args:
            extract_path: String, a path include extracted files.

        Raises:
            errors.BootImgDoesNotExist: boot.img doesn't exist.
            errors.UnpackBootImageError: Unpack boot.img fail.
        """
        bootimg_path = os.path.join(extract_path, _BOOT_IMAGE)
        if not os.path.exists(bootimg_path):
            raise errors.BootImgDoesNotExist(
                "%s does not exist in %s" % (_BOOT_IMAGE, bootimg_path))

        logger.info("Start to unpack boot.img.")
        try:
            subprocess.check_call(
                UNPACK_BOOTIMG_CMD % (bootimg_path, extract_path),
                shell=True)
        except subprocess.CalledProcessError as e:
            raise errors.UnpackBootImageError(
                "Failed to unpack boot.img: %s" % str(e))
        logger.info("Unpack boot.img complete!")

    @staticmethod
    def _AclCfImageFiles(extract_path):
        """ACL related files.

        Use setfacl so that libvirt does not lose access to this file if user
        does anything to this file at any point.

        Args:
            extract_path: String, a path include extracted files.
        """
        image_list = glob.glob(os.path.join(extract_path, "*.img"))
        logger.info("Start to set ACLs on files: %s", ",".join(image_list))
        for image_path in image_list:
            subprocess.check_call(ACL_CMD % image_path, shell=True)
        logger.info("The ACLs have set completed!")

    @staticmethod
    def _ConfirmDownloadRemoteImageDir(download_dir):
        """Confirm download remote image directory.

        If available space of download_dir is less than _REQUIRED_SPACE, ask
        the user to choose a different d/l dir or to exit out since acloud will
        fail to download the artifacts due to insufficient disk space.

        Args:
            download_dir: String, a directory for download and decompress.

        Returns:
            String, Specific download directory when user confirm to change.
        """
        while True:
            download_dir = os.path.expanduser(download_dir)
            if not os.path.exists(download_dir):
                answer = utils.InteractWithQuestion(
                    "No such directory %s.\nEnter 'y' to create it, enter "
                    "anything else to exit out[y/N]: " % download_dir)
                if answer.lower() == "y":
                    os.makedirs(download_dir)
                else:
                    sys.exit(constants.EXIT_BY_USER)

            stat = os.statvfs(download_dir)
            available_space = stat.f_bavail*stat.f_bsize/(1024)**3
            if available_space < _REQUIRED_SPACE:
                download_dir = utils.InteractWithQuestion(
                    _CONFIRM_DOWNLOAD_DIR % {"download_dir":download_dir,
                                             "available_space":available_space,
                                             "required_space":_REQUIRED_SPACE})
                if download_dir.lower() == "q":
                    sys.exit(constants.EXIT_BY_USER)
            else:
                return download_dir
