#!/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"""Create entry point.

Create will handle all the logic related to creating a local/remote instance
an Android Virtual Device and the logic related to prepping the local/remote
image artifacts.
"""

from __future__ import print_function

import os
import subprocess
import sys

from acloud import errors
from acloud.create import avd_spec
from acloud.create import cheeps_remote_image_remote_instance
from acloud.create import gce_local_image_remote_instance
from acloud.create import gce_remote_image_remote_instance
from acloud.create import goldfish_local_image_local_instance
from acloud.create import goldfish_remote_image_remote_instance
from acloud.create import local_image_local_instance
from acloud.create import local_image_remote_instance
from acloud.create import local_image_remote_host
from acloud.create import remote_image_remote_instance
from acloud.create import remote_image_local_instance
from acloud.create import remote_image_remote_host
from acloud.internal import constants
from acloud.internal.lib import utils
from acloud.setup import setup
from acloud.setup import gcp_setup_runner
from acloud.setup import host_setup_runner


_MAKE_CMD = "build/soong/soong_ui.bash"
_MAKE_ARG = "--make-mode"
_YES = "y"

_CREATOR_CLASS_DICT = {
    # GCE types
    (constants.TYPE_GCE, constants.IMAGE_SRC_LOCAL, constants.INSTANCE_TYPE_REMOTE):
        gce_local_image_remote_instance.GceLocalImageRemoteInstance,
    (constants.TYPE_GCE, constants.IMAGE_SRC_REMOTE, constants.INSTANCE_TYPE_REMOTE):
        gce_remote_image_remote_instance.GceRemoteImageRemoteInstance,
    # CF types
    (constants.TYPE_CF, constants.IMAGE_SRC_LOCAL, constants.INSTANCE_TYPE_LOCAL):
        local_image_local_instance.LocalImageLocalInstance,
    (constants.TYPE_CF, constants.IMAGE_SRC_LOCAL, constants.INSTANCE_TYPE_REMOTE):
        local_image_remote_instance.LocalImageRemoteInstance,
    (constants.TYPE_CF, constants.IMAGE_SRC_LOCAL, constants.INSTANCE_TYPE_HOST):
        local_image_remote_host.LocalImageRemoteHost,
    (constants.TYPE_CF, constants.IMAGE_SRC_REMOTE, constants.INSTANCE_TYPE_REMOTE):
        remote_image_remote_instance.RemoteImageRemoteInstance,
    (constants.TYPE_CF, constants.IMAGE_SRC_REMOTE, constants.INSTANCE_TYPE_LOCAL):
        remote_image_local_instance.RemoteImageLocalInstance,
    (constants.TYPE_CF, constants.IMAGE_SRC_REMOTE, constants.INSTANCE_TYPE_HOST):
        remote_image_remote_host.RemoteImageRemoteHost,
    # Cheeps types
    (constants.TYPE_CHEEPS, constants.IMAGE_SRC_REMOTE, constants.INSTANCE_TYPE_REMOTE):
        cheeps_remote_image_remote_instance.CheepsRemoteImageRemoteInstance,
    # GF types
    (constants.TYPE_GF, constants.IMAGE_SRC_REMOTE, constants.INSTANCE_TYPE_REMOTE):
        goldfish_remote_image_remote_instance.GoldfishRemoteImageRemoteInstance,
    (constants.TYPE_GF, constants.IMAGE_SRC_LOCAL, constants.INSTANCE_TYPE_LOCAL):
        goldfish_local_image_local_instance.GoldfishLocalImageLocalInstance,
    # FVP types
    (constants.TYPE_FVP, constants.IMAGE_SRC_LOCAL, constants.INSTANCE_TYPE_REMOTE):
        local_image_remote_instance.LocalImageRemoteInstance,
}


def GetAvdCreatorClass(avd_type, instance_type, image_source):
    """Return the creator class for the specified spec.

    Based on the image source and the instance type, return the proper
    creator class.

    Args:
        avd_type: String, the AVD type(cuttlefish, gce).
        instance_type: String, the AVD instance type (local or remote).
        image_source: String, the source of the image (local or remote).

    Returns:
        An AVD creator class (e.g. LocalImageRemoteInstance).

    Raises:
        UnsupportedInstanceImageType if argments didn't match _CREATOR_CLASS_DICT.
    """
    creator_class = _CREATOR_CLASS_DICT.get(
        (avd_type, image_source, instance_type))

    if not creator_class:
        raise errors.UnsupportedInstanceImageType(
            "unsupported creation of avd type: %s, instance type: %s, "
            "image source: %s" % (avd_type, instance_type, image_source))
    return creator_class

def _CheckForAutoconnect(args):
    """Check that we have all prerequisites for autoconnect.

    Autoconnect requires adb and ssh, we'll just check for adb for now and
    assume ssh is everywhere. If adb isn't around, ask the user if they want us
    to build it, if not we'll disable autoconnect.

    Args:
        args: Namespace object from argparse.parse_args.
    """
    if not args.autoconnect or utils.FindExecutable(constants.ADB_BIN):
        return

    disable_autoconnect = False
    answer = _YES if args.no_prompt else utils.InteractWithQuestion(
        "adb is required for autoconnect, without it autoconnect will be "
        "disabled, would you like acloud to build it[y/N]? ")
    if answer in constants.USER_ANSWER_YES:
        utils.PrintColorString("Building adb ... ", end="")
        android_build_top = os.environ.get(
            constants.ENV_ANDROID_BUILD_TOP)
        if not android_build_top:
            utils.PrintColorString("Fail! (Not in a lunch'd env)",
                                   utils.TextColors.FAIL)
            disable_autoconnect = True
        else:
            make_cmd = os.path.join(android_build_top, _MAKE_CMD)
            build_adb_cmd = [make_cmd, _MAKE_ARG, "adb"]
            try:
                with open(os.devnull, "w") as dev_null:
                    subprocess.check_call(build_adb_cmd, stderr=dev_null,
                                          stdout=dev_null)
                    utils.PrintColorString("OK!", utils.TextColors.OKGREEN)
            except subprocess.CalledProcessError:
                utils.PrintColorString("Fail! (build failed)",
                                       utils.TextColors.FAIL)
                disable_autoconnect = True
    else:
        disable_autoconnect = True

    if disable_autoconnect:
        utils.PrintColorString("Disabling autoconnect",
                               utils.TextColors.WARNING)
        args.autoconnect = False


def _CheckForSetup(args):
    """Check that host is setup to run the create commands.

    We'll check we have the necessary bits setup to do what the user wants, and
    if not, tell them what they need to do before running create again.

    Args:
        args: Namespace object from argparse.parse_args.
    """
    # Need to set all these so if we need to run setup, it won't barf on us
    # because of some missing fields.
    args.gcp_init = False
    args.host = False
    args.host_base = False
    args.force = False
    args.update_config = None
    # Remote image/instance requires the GCP config setup.
    if not args.local_instance or args.local_image == "":
        gcp_setup = gcp_setup_runner.GcpTaskRunner(args.config_file)
        if gcp_setup.ShouldRun():
            args.gcp_init = True

    # Local instance requires host to be setup. We'll assume that if the
    # packages were installed, then the user was added into the groups. This
    # avoids the scenario where a user runs setup and creates a local instance.
    # The following local instance create will trigger this if statment and go
    # through the whole setup again even though it's already done because the
    # user groups aren't set until the user logs out and back in.
    if args.local_instance:
        host_pkg_setup = host_setup_runner.AvdPkgInstaller()
        if host_pkg_setup.ShouldRun():
            args.host = True

    # Install base packages if we haven't already.
    host_base_setup = host_setup_runner.HostBasePkgInstaller()
    if host_base_setup.ShouldRun():
        args.host_base = True

    run_setup = args.force or args.gcp_init or args.host or args.host_base

    if run_setup:
        answer = utils.InteractWithQuestion("Missing necessary acloud setup, "
                                            "would you like to run setup[y/N]?")
        if answer in constants.USER_ANSWER_YES:
            setup.Run(args)
        else:
            print("Please run '#acloud setup' so we can get your host setup")
            sys.exit(constants.EXIT_BY_USER)


def PreRunCheck(args):
    """Do some pre-run checks to ensure a smooth create experience.

    Args:
        args: Namespace object from argparse.parse_args.
    """
    _CheckForSetup(args)
    _CheckForAutoconnect(args)


def Run(args):
    """Run create.

    Args:
        args: Namespace object from argparse.parse_args.

    Returns:
        A Report instance.
    """
    if not args.skip_pre_run_check:
        PreRunCheck(args)
    spec = avd_spec.AVDSpec(args)
    avd_creator_class = GetAvdCreatorClass(spec.avd_type,
                                           spec.instance_type,
                                           spec.image_source)
    avd_creator = avd_creator_class()
    report = avd_creator.Create(spec, args.no_prompt)
    return report
