#!/usr/bin/env python3
#
# Copyright 2018 The Bazel Authors. All rights reserved.
#
# 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.

import collections
import json
import re
import subprocess
import threading
import time

DEBUG = True
PRINT_LOCK = threading.Lock()


def debug(*args, **kwargs):
    if DEBUG:
        with PRINT_LOCK:
            print(*args, **kwargs)


def is_sequence(seq):
    return isinstance(seq, collections.abc.Sequence) and not isinstance(seq, str)


def gcloud(*args, **kwargs):
    cmd = ["gcloud"]
    cmd += args
    for flag, value in kwargs.items():
        # Optionally strip counter suffixes to make it possible to specify the same flag multiple
        # times, even though it's passed here via a dict.
        if re.search(r"_\d$", flag):
            flag = flag[:-2]
        # Python uses underscores as word delimiters in kwargs, but gcloud wants dashes.
        flag = flag.replace("_", "-")
        if isinstance(value, bool):
            cmd += ["--" + ("no-" if not value else "") + flag]
        # We convert key=[a, b] into two flags: --key=a --key=b.
        elif is_sequence(value):
            for item in value:
                cmd += ["--" + flag, str(item)]
        else:
            cmd += ["--" + flag, str(value)]
    # Throws `subprocess.CalledProcessError` if the process exits with return code > 0.

    if not "get-serial-port-output" in cmd:
        debug("Running: " + " ".join(cmd))

    max_attempts = 3
    for attempt in range(max_attempts):
        try:
            return subprocess.run(
                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, check=True
            )
        except subprocess.CalledProcessError as e:
            # When multiple threads invoke gcloud concurrently in a fresh environment,
            # multiple processes race to initialize and migrate gcloud's local SQLite
            # database (~/.config/gcloud/), causing transient collisions such as:
            # "ERROR: gcloud crashed (OperationalError): duplicate column name: regional_access_boundary".
            # Example failure: https://buildkite.com/bazel-trusted/create-linux-vm-image/builds/43#019ff552-6791-4b7a-95c4-2c7c882bcfd5
            # Retrying allows subsequent attempts to succeed once the initial migration completes.
            if attempt < max_attempts - 1 and "OperationalError" in e.stderr:
                debug(f"gcloud crashed with OperationalError on attempt {attempt + 1}, retrying...")
                time.sleep(1)
                continue
            raise


def create_instance(name, **kwargs):
    try:
        return gcloud("compute", "instances", "create", name, **kwargs)
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def delete_instance(name, **kwargs):
    try:
        return gcloud("compute", "instances", "delete", name, "--quiet", **kwargs)
    except subprocess.CalledProcessError as e:
        # It's not an error if 'delete' failed, because the object didn't exist in the first place.
        # But we do want to error out on other unexpected errors.
        if not re.search(r"The resource .* was not found", e.stderr):
            raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))
        return e


def describe_instance(name, **kwargs):
    try:
        return gcloud("compute", "instances", "describe", name, **kwargs)
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def create_instance_group(name, **kwargs):
    try:
        return gcloud("compute", "instance-groups", "managed", "create", name, **kwargs)
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def delete_instance_group(name, **kwargs):
    try:
        return gcloud("compute", "instance-groups", "managed", "delete", name, "--quiet", **kwargs)
    except subprocess.CalledProcessError as e:
        # It's not an error if 'delete' failed, because the object didn't exist in the first place.
        # But we do want to error out on other unexpected errors.
        if not re.search(r"The resource .* was not found", e.stderr):
            raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))
        return e


def rolling_update_instance_group(name, **kwargs):
    try:
        return gcloud(
            "compute",
            "instance-groups",
            "managed",
            "rolling-action",
            "start-update",
            name,
            **kwargs,
        )
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def set_autoscaling_instance_groups(name, **kwargs):
    try:
        return gcloud("compute", "instance-groups", "managed", "set-autoscaling", name, **kwargs)
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def create_instance_template(name, **kwargs):
    try:
        return gcloud("compute", "instance-templates", "create", name, **kwargs)
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def delete_instance_template(name, **kwargs):
    try:
        return gcloud("compute", "instance-templates", "delete", name, "--quiet", **kwargs)
    except subprocess.CalledProcessError as e:
        # It's not an error if 'delete' failed, because the object didn't exist in the first place.
        # But we do want to error out on other unexpected errors.
        if not re.search(r"The resource .* was not found", e.stderr):
            raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))
        return e


def create_image(name, **kwargs):
    try:
        return gcloud("compute", "images", "create", name, **kwargs)
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def describe_image_family(name, **kwargs):
    try:
        return json.loads(
            gcloud(
                "compute", "images", "describe-from-family", "--format=json", name, **kwargs
            ).stdout
        )
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def reset_windows_password(name, **kwargs):
    try:
        return gcloud("compute", "reset-windows-password", name, "--quiet", **kwargs)
    except subprocess.CalledProcessError as e:
        raise Exception('"{}" returned unexpected error:\n{}'.format(e.cmd, e.stderr))


def get_serial_port_output(name, **kwargs):
    return gcloud("compute", "instances", "get-serial-port-output", name, **kwargs)
