# Copyright 2015 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A convinient wrapper of the GCE python API.

Public methods in class GceContext raise HttpError when the underlining call to
Google API fails, or gce.Error on other failures.
"""

import logging

from chromite.third_party import httplib2
from chromite.third_party.googleapiclient.discovery import build
from chromite.third_party.googleapiclient.errors import HttpError
from chromite.third_party.googleapiclient.http import HttpRequest
from chromite.third_party.oauth2client.client import GoogleCredentials

from chromite.lib import timeout_util


class Error(Exception):
    """Base exception for this module."""


class ResourceNotFoundError(Error):
    """Exceptions raised when requested GCE resource was not found."""


class RetryOnServerErrorHttpRequest(HttpRequest):
    """A HttpRequest that will be retried on server errors automatically."""

    def __init__(self, num_retries, *args, **kwargs):
        """Constructor for RetryOnServerErrorHttpRequest."""
        self.num_retries = num_retries
        super().__init__(*args, **kwargs)

    def execute(self, http=None, num_retries=None):
        """Excutes a RetryOnServerErrorHttpRequest.

        HttpRequest.execute() has the option of automatically retrying on server
        errors, i.e., 500 status codes. Call it with a non-zero value of
        |num_retries| will cause failed requests to be retried.

        Args:
            http: The httplib2.http to send this request through.
            num_retries: Number of retries. Class default value will be used if
                omitted.

        Returns:
            A deserialized object model of the response body as determined
            by the postproc. See HttpRequest.execute().
        """
        return super().execute(
            http=http, num_retries=num_retries or self.num_retries
        )


def _GetMetadataValue(metadata, key):
    """Finds a value corresponding to a given metadata key.

    Args:
        metadata: metadata object, i.e. a dict containing 'items'
            - a list of key-value pairs.
        key: name of the key.

    Returns:
        Corresponding value or None if it was not found.
    """
    for item in metadata["items"]:
        if item["key"] == key:
            return item["value"]
    return None


def _UpdateMetadataValue(metadata, key, value):
    """Updates a single key-value pair in a metadata object.

    Args:
        metadata: metadata object, i.e. a dict containing 'items'
            - a list of key-value pairs.
        key: name of the key.
        value: new value for the key, or None if it should be removed.
    """
    items = metadata.setdefault("items", [])
    for item in items:
        if item["key"] == key:
            if value is None:
                items.remove(item)
            else:
                item["value"] = value
            return

    if value is not None:
        items.append(
            {
                "key": key,
                "value": value,
            }
        )


class GceContext(object):
    """A convenient wrapper around the GCE Python API."""

    # These constants are made public so that users can customize as they need.
    DEFAULT_TIMEOUT_SEC = 5 * 60
    INSTANCE_OPERATIONS_TIMEOUT_SEC = 10 * 60
    IMAGE_OPERATIONS_TIMEOUT_SEC = 10 * 60

    _GCE_SCOPES = (
        # CreateInstance, CreateImage
        "https://www.googleapis.com/auth/compute",
        # CreateImage
        "https://www.googleapis.com/auth/devstorage.full_control",
    )
    _DEFAULT_NETWORK = "default"
    _DEFAULT_MACHINE_TYPE = "n1-standard-8"

    # Project default service account and scopes.
    _DEFAULT_SERVICE_ACCOUNT_EMAIL = "default"
    # The list is in line with what the gcloud cli uses.
    # https://cloud.google.com/sdk/gcloud/reference/compute/instances/create
    _DEFAULT_INSTANCE_SCOPES = [
        "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
        "https://www.googleapis.com/auth/devstorage.read_only",
        "https://www.googleapis.com/auth/logging.write",
    ]

    # This is made public to allow easy customization of the retry behavior.
    RETRIES = 2

    def __init__(self, project, zone, credentials, thread_safe=False):
        """Initializes GceContext.

        Args:
            project: The GCP project to create instances in.
            zone: The default zone to create instances in.
            credentials: The credentials used to call the GCE API.
            thread_safe: Whether the client is expected to be thread safe.
        """
        self.project = project
        self.zone = zone

        def _BuildRequest(http, *args, **kwargs):
            """Custom request builder."""
            return self._BuildRetriableRequest(
                self.RETRIES, http, thread_safe, credentials, *args, **kwargs
            )

        self.gce_client = build(
            "compute",
            "v1",
            credentials=credentials,
            requestBuilder=_BuildRequest,
        )

        self.region = self.GetZoneRegion(zone)

    @classmethod
    def ForServiceAccount(cls, project, zone, json_key_file):
        """Creates a GceContext using service account credentials.

        About service account:
        https://developers.google.com/api-client-library/python/auth/service-accounts

        Args:
            project: The GCP project to create images and instances in.
            zone: The default zone to create instances in.
            json_key_file: Path to the service account JSON key.

        Returns:
            GceContext.
        """
        credentials = GoogleCredentials.from_stream(
            json_key_file
        ).create_scoped(cls._GCE_SCOPES)
        return GceContext(project, zone, credentials)

    @classmethod
    def ForServiceAccountThreadSafe(cls, project, zone, json_key_file):
        """Creates a thread-safe GceContext using service account credentials.

        About service account:
        https://developers.google.com/api-client-library/python/auth/service-accounts

        Args:
            project: The GCP project to create images and instances in.
            zone: The default zone to create instances in.
            json_key_file: Path to the service account JSON key.

        Returns:
            GceContext.
        """
        credentials = GoogleCredentials.from_stream(
            json_key_file
        ).create_scoped(cls._GCE_SCOPES)
        return GceContext(project, zone, credentials, thread_safe=True)

    def CreateAddress(self, name, region=None):
        """Reserves an external IP address.

        Args:
            name: The name to assign to the address.
            region: Region to reserve the address in.

        Returns:
            The reserved address as a string.
        """
        body = {
            "name": name,
        }
        operation = (
            self.gce_client.addresses()
            .insert(
                project=self.project, region=region or self.region, body=body
            )
            .execute()
        )
        self._WaitForRegionOperation(
            operation["name"],
            region,
            timeout_sec=self.INSTANCE_OPERATIONS_TIMEOUT_SEC,
        )

        address = (
            self.gce_client.addresses()
            .get(
                project=self.project, region=region or self.region, address=name
            )
            .execute()
        )

        return address["address"]

    def DeleteAddress(self, name, region=None):
        """Frees up an external IP address.

        Args:
            name: The name of the address.
            region: Region of the address.
        """
        operation = (
            self.gce_client.addresses()
            .delete(
                project=self.project, region=region or self.region, address=name
            )
            .execute()
        )
        self._WaitForRegionOperation(
            operation["name"],
            region=region or self.region,
            timeout_sec=self.INSTANCE_OPERATIONS_TIMEOUT_SEC,
        )

    def GetZoneRegion(self, zone=None):
        """Resolves name of the region that a zone belongs to.

        Args:
            zone: The zone to resolve.

        Returns:
            Name of the region corresponding to the zone.
        """
        zone_resource = (
            self.gce_client.zones()
            .get(project=self.project, zone=zone or self.zone)
            .execute()
        )
        return zone_resource["region"].split("/")[-1]

    def CreateInstance(
        self,
        name,
        image,
        zone=None,
        network=None,
        subnet=None,
        machine_type=None,
        default_scopes=True,
        static_address=None,
        **kwargs,
    ):
        """Creates an instance with the given image and waits until it's ready.

        Args:
            name: Instance name.
            image: Fully spelled URL of the image, e.g., for private images,
                'global/images/my-private-image', or for images from a
                publicly-available project,
                'projects/debian-cloud/global/images/debian-7-wheezy-vYYYYMMDD'.
                Details:
                https://cloud.google.com/compute/docs/reference/latest/instances/insert
            zone: The zone to create the instance in. Default zone will be used
                if omitted.
            network: An existing network to create the instance in. Default
                network will be used if omitted.
            subnet: The subnet to create the instance in.
            machine_type: The machine type to use. Default machine type will be
                used if omitted.
            default_scopes: If true, the default scopes are added to the
                instances.
            static_address: External IP address to assign to the instance as a
                string. If None an ephemeral address will be used.
            **kwargs: Other possible Instance Resource properties.
                https://cloud.google.com/compute/docs/reference/latest/instances#resource
                Note that values from kwargs will overrule properties
                constructed from positional arguments, i.e., name, image, zone,
                network and machine_type.

        Returns:
            URL to the created instance.
        """
        logging.info('Creating instance "%s" with image "%s" ...', name, image)
        network = "global/networks/%s" % network or self._DEFAULT_NETWORK
        machine_type = "zones/%s/machineTypes/%s" % (
            zone or self.zone,
            machine_type or self._DEFAULT_MACHINE_TYPE,
        )
        service_accounts = (
            (
                {
                    "email": self._DEFAULT_SERVICE_ACCOUNT_EMAIL,
                    "scopes": self._DEFAULT_INSTANCE_SCOPES,
                },
            )
            if default_scopes
            else ()
        )

        config = {
            "name": name,
            "machineType": machine_type,
            "disks": (
                {
                    "boot": True,
                    "autoDelete": True,
                    "initializeParams": {
                        "sourceImage": image,
                    },
                },
            ),
            "networkInterfaces": (
                {
                    "network": network,
                    "accessConfigs": (
                        {
                            "type": "ONE_TO_ONE_NAT",
                            "name": "External NAT",
                        },
                    ),
                },
            ),
            "serviceAccounts": service_accounts,
        }
        config.update(**kwargs)
        if static_address is not None:
            config["networkInterfaces"][0]["accessConfigs"][0][
                "natIP"
            ] = static_address
        if subnet is not None:
            region = self.GetZoneRegion(zone)
            config["networkInterfaces"][0][
                "subnetwork"
            ] = "regions/%s/subnetworks/%s" % (region, subnet)
        operation = (
            self.gce_client.instances()
            .insert(project=self.project, zone=zone or self.zone, body=config)
            .execute()
        )
        self._WaitForZoneOperation(
            operation["name"],
            timeout_sec=self.INSTANCE_OPERATIONS_TIMEOUT_SEC,
            timeout_handler=lambda: self.DeleteInstance(name),
        )
        return operation["targetLink"]

    def DeleteInstance(self, name, zone=None):
        """Deletes an instance with the name and waits until it's done.

        Args:
            name: Name of the instance to delete.
            zone: Zone where the instance is in. Default zone will be used if
                omitted.
        """
        logging.info('Deleting instance "%s" ...', name)
        operation = (
            self.gce_client.instances()
            .delete(project=self.project, zone=zone or self.zone, instance=name)
            .execute()
        )
        self._WaitForZoneOperation(
            operation["name"], timeout_sec=self.INSTANCE_OPERATIONS_TIMEOUT_SEC
        )

    def StartInstance(self, name, zone=None):
        """Starts an instance with the name and waits until it's done.

        Args:
            name: Name of the instance to start.
            zone: Zone where the instance is in. Default zone will be used if
                omitted.
        """
        logging.info('Starting instance "%s" ...', name)
        operation = (
            self.gce_client.instances()
            .start(project=self.project, zone=zone or self.zone, instance=name)
            .execute()
        )
        self._WaitForZoneOperation(
            operation["name"], timeout_sec=self.INSTANCE_OPERATIONS_TIMEOUT_SEC
        )

    def StopInstance(self, name, zone=None):
        """Stops an instance with the name and waits until it's done.

        Args:
            name: Name of the instance to stop.
            zone: Zone where the instance is in. Default zone will be used if
                omitted.
        """
        logging.info('Stopping instance "%s" ...', name)
        operation = (
            self.gce_client.instances()
            .stop(project=self.project, zone=zone or self.zone, instance=name)
            .execute()
        )
        self._WaitForZoneOperation(
            operation["name"], timeout_sec=self.INSTANCE_OPERATIONS_TIMEOUT_SEC
        )

    def CreateImage(self, name, source):
        """Creates an image with the given |source|.

        Args:
            name: Name of the image to be created.
            source: Google Cloud Storage object of the source disk. e.g.:
                https://storage.googleapis.com/my-gcs-bucket/test_image.tar.gz

        Returns:
            URL to the created image.
        """
        logging.info('Creating image "%s" with "source" %s ...', name, source)
        config = {
            "name": name,
            "rawDisk": {
                "source": source,
            },
        }
        operation = (
            self.gce_client.images()
            .insert(project=self.project, body=config)
            .execute()
        )
        self._WaitForGlobalOperation(
            operation["name"],
            timeout_sec=self.IMAGE_OPERATIONS_TIMEOUT_SEC,
            timeout_handler=lambda: self.DeleteImage(name),
        )
        return operation["targetLink"]

    def DeleteImage(self, name):
        """Deletes an image and waits until it's deleted.

        Args:
            name: Name of the image to delete.
        """
        logging.info('Deleting image "%s" ...', name)
        operation = (
            self.gce_client.images()
            .delete(project=self.project, image=name)
            .execute()
        )
        self._WaitForGlobalOperation(
            operation["name"], timeout_sec=self.IMAGE_OPERATIONS_TIMEOUT_SEC
        )

    def ListInstances(self, zone=None):
        """Lists all instances.

        Args:
            zone: Zone where the instances are in. Default zone will be used if
                omitted.

        Returns:
            A list of Instance Resources if found, or an empty list otherwise.
        """
        result = (
            self.gce_client.instances()
            .list(project=self.project, zone=zone or self.zone)
            .execute()
        )
        return result.get("items", [])

    def ListImages(self):
        """Lists all images.

        Returns:
            A list of Image Resources if found, or an empty list otherwise.
        """
        result = self.gce_client.images().list(project=self.project).execute()
        return result.get("items", [])

    def GetInstance(self, instance, zone=None):
        """Gets an Instance Resource by name and zone.

        Args:
            instance: Name of the instance.
            zone: Zone where the instance is in. Default zone will be used if
                omitted.

        Returns:
            An Instance Resource.

        Raises:
            ResourceNotFoundError: if instance was not found.
            HttpError: other HTTP failures.
        """
        try:
            return (
                self.gce_client.instances()
                .get(
                    project=self.project,
                    zone=zone or self.zone,
                    instance=instance,
                )
                .execute()
            )
        except HttpError as e:
            if e.resp.status == 404:
                raise ResourceNotFoundError(
                    'Instance "%s" for project "%s" in zone "%s" was not found.'
                    % (instance, self.project, zone or self.zone)
                )
            else:
                raise

    def GetInstanceIP(self, instance, zone=None):
        """Gets the external IP of an instance.

        Args:
            instance: Name of the instance to get IP for.
            zone: Zone where the instance is in. Default zone will be used if
                omitted.

        Returns:
            External IP address of the instance.

        Raises:
            Error: Something went wrong when trying to get IP for the instance.
        """
        result = self.GetInstance(instance, zone)
        try:
            return result["networkInterfaces"][0]["accessConfigs"][0]["natIP"]
        except (KeyError, IndexError):
            raise Error("Failed to get IP address for instance %s" % instance)

    def GetInstanceInternalIP(self, instance, zone=None):
        """Gets the internal IP of an instance."""
        result = self.GetInstance(instance, zone)
        try:
            return result["networkInterfaces"][0]["networkIP"]
        except (KeyError, IndexError):
            raise Error("Failed to get internal IP for instance %s" % instance)

    def GetImage(self, image):
        """Gets an Image Resource by name.

        Args:
            image: Name of the image to look for.

        Returns:
            An Image Resource.

        Raises:
            ResourceNotFoundError: The requested image was not found.
        """
        try:
            return (
                self.gce_client.images()
                .get(project=self.project, image=image)
                .execute()
            )
        except HttpError as e:
            if e.resp.status == 404:
                raise ResourceNotFoundError(
                    'Image "%s" for project "%s" was not found.'
                    % (image, self.project)
                )
            else:
                raise

    def InstanceExists(self, instance, zone=None):
        """Checks if an instance exists in the current project.

        Args:
            instance: Name of the instance to check existence of.
            zone: Zone where the instance is in. Default zone will be used if
                omitted.

        Returns:
            True if the instance exists or False otherwise.
        """
        try:
            return self.GetInstance(instance, zone) is not None
        except ResourceNotFoundError:
            return False

    def ImageExists(self, image):
        """Checks if an image exists in the current project.

        Args:
            image: Name of the image to check existence of.

        Returns:
            True if the instance exists or False otherwise.
        """
        try:
            return self.GetImage(image) is not None
        except ResourceNotFoundError:
            return False

    def GetCommonInstanceMetadata(self, key):
        """Looks up a single project metadata value.

        Args:
            key: Metadata key name.

        Returns:
            Metadata value corresponding to the key, or None if it was not
            found.
        """
        projects_data = (
            self.gce_client.projects().get(project=self.project).execute()
        )
        metadata = projects_data["commonInstanceMetadata"]
        return _GetMetadataValue(metadata, key)

    def SetCommonInstanceMetadata(self, key, value):
        """Sets a single project metadata value.

        Args:
            key: Metadata key to be set.
            value: New value, or None if the given key should be removed.
        """
        projects_data = (
            self.gce_client.projects().get(project=self.project).execute()
        )
        metadata = projects_data["commonInstanceMetadata"]
        _UpdateMetadataValue(metadata, key, value)
        operation = (
            self.gce_client.projects()
            .setCommonInstanceMetadata(project=self.project, body=metadata)
            .execute()
        )
        self._WaitForGlobalOperation(operation["name"])

    def GetInstanceMetadata(self, instance, key):
        """Looks up instance's metadata value.

        Args:
            instance: Name of the instance.
            key: Metadata key name.

        Returns:
            Metadata value corresponding to the key, or None if it was not
            found.
        """
        instance_data = self.GetInstance(instance)
        metadata = instance_data["metadata"]
        return _GetMetadataValue(metadata, key)

    def SetInstanceMetadata(self, instance, key, value):
        """Sets a single instance metadata value.

        Args:
            instance: Name of the instance.
            key: Metadata key to be set.
            value: New value, or None if the given key should be removed.
        """
        instance_data = self.GetInstance(instance)
        metadata = instance_data["metadata"]
        _UpdateMetadataValue(metadata, key, value)
        operation = (
            self.gce_client.instances()
            .setMetadata(
                project=self.project,
                zone=self.zone,
                instance=instance,
                body=metadata,
            )
            .execute()
        )
        self._WaitForZoneOperation(operation["name"])

    def _WaitForZoneOperation(
        self, operation, zone=None, timeout_sec=None, timeout_handler=None
    ):
        """Waits until a GCE ZoneOperation is finished or timed out.

        Args:
            operation: The GCE operation to wait for.
            zone: The zone that |operation| belongs to.
            timeout_sec: The maximum number of seconds to wait for.
            timeout_handler: A callable to be executed when timeout happens.

        Raises:
            Error when timeout happens or the operation fails.
        """
        get_request = self.gce_client.zoneOperations().get(
            project=self.project, zone=zone or self.zone, operation=operation
        )
        self._WaitForOperation(
            operation, get_request, timeout_sec, timeout_handler=timeout_handler
        )

    def _WaitForRegionOperation(
        self, operation, region, timeout_sec=None, timeout_handler=None
    ):
        """Waits until a GCE RegionOperation is finished or timed out.

        Args:
            operation: The GCE operation to wait for.
            region: The region that |operation| belongs to.
            timeout_sec: The maximum number of seconds to wait for.
            timeout_handler: A callable to be executed when timeout happens.

        Raises:
            Error when timeout happens or the operation fails.
        """
        get_request = self.gce_client.regionOperations().get(
            project=self.project,
            region=region or self.region,
            operation=operation,
        )
        self._WaitForOperation(
            operation, get_request, timeout_sec, timeout_handler=timeout_handler
        )

    def _WaitForGlobalOperation(
        self, operation, timeout_sec=None, timeout_handler=None
    ):
        """Waits until a GCE GlobalOperation is finished or timed out.

        Args:
            operation: The GCE operation to wait for.
            timeout_sec: The maximum number of seconds to wait for.
            timeout_handler: A callable to be executed when timeout happens.

        Raises:
            Error when timeout happens or the operation fails.
        """
        get_request = self.gce_client.globalOperations().get(
            project=self.project, operation=operation
        )
        self._WaitForOperation(
            operation,
            get_request,
            timeout_sec=timeout_sec,
            timeout_handler=timeout_handler,
        )

    def _WaitForOperation(
        self,
        operation,
        get_operation_request,
        timeout_sec=None,
        timeout_handler=None,
    ):
        """Waits until timeout, or it receives a response with a 'DONE' status.

        Args:
            operation: The GCE operation to wait for.
            get_operation_request: The HTTP request to get the operation's
                status. This request will be executed periodically until it
                returns a status 'DONE'.
            timeout_sec: The maximum number of seconds to wait for.
            timeout_handler: A callable to be executed when times out.

        Raises:
            Error when timeout happens or the operation fails.
        """

        def _IsDone():
            result = get_operation_request.execute()
            if result["status"] == "DONE":
                if "error" in result:
                    raise Error(result["error"])
                return True
            return False

        try:
            timeout = timeout_sec or self.DEFAULT_TIMEOUT_SEC
            logging.info(
                "Waiting up to %d seconds for operation [%s] to complete...",
                timeout,
                operation,
            )
            timeout_util.WaitForReturnTrue(_IsDone, timeout, period=1)
        except timeout_util.TimeoutError:
            if timeout_handler:
                timeout_handler()
            raise Error(
                "Timeout waiting for operation [%s] to complete" % operation
            )

    def _BuildRetriableRequest(
        self,
        num_retries,
        http,
        thread_safe=False,
        credentials=None,
        *args,
        **kwargs,
    ):
        """Builds a request that will be automatically retried on server errors.

        Args:
            num_retries: The maximum number of times to retry until give up.
            http: An httplib2.Http object that this request will be executed
                through.
            thread_safe: Whether the request needs to be thread-safe.
            credentials: Credentials to apply to the request.
            *args: Optional positional arguments.
            **kwargs: Optional keyword arguments.

        Returns:
            RetryOnServerErrorHttpRequest: A request that will automatically
                retry on server errors.
        """
        if thread_safe:
            # Create a new http object for every request.
            http = credentials.authorize(httplib2.Http())
        return RetryOnServerErrorHttpRequest(num_retries, http, *args, **kwargs)
