#!/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 argparse
from datetime import datetime
import os
import queue
import sys
import threading
import yaml

import gcloud

WORK_QUEUE = queue.Queue()


def worker():
    while True:
        item = WORK_QUEUE.get()
        if not item:
            break
        try:
            # We take a few keys out of the config item. The rest is passed
            # as-is to create_instance_template() and thus to the gcloud
            # command line tool.
            count = item.pop("count")
            instance_group_name = item.pop("name")
            project = item.pop("project")
            zone = item.pop("zone", None)
            region = item.pop("region", None)
            health_check = item.pop("health_check", None)
            initial_delay = item.pop("initial_delay", None)

            if not project:
                raise Exception("Invalid instance config, no project name set")

            if not zone and not region:
                raise Exception("Invalid instance config, either zone or region must be specified")

            timestamp = datetime.now().strftime("%Y%m%dt%H%M%S")
            template_name = "{}-{}".format(instance_group_name, timestamp)

            if zone is not None:
                if (
                    gcloud.delete_instance_group(
                        instance_group_name, project=project, zone=zone
                    ).returncode
                    == 0
                ):
                    print("Deleted existing instance group: {}".format(instance_group_name))
            elif region is not None:
                if (
                    gcloud.delete_instance_group(
                        instance_group_name, project=project, region=region
                    ).returncode
                    == 0
                ):
                    print("Deleted existing instance group: {}".format(instance_group_name))

            # Create the new instance template.
            gcloud.create_instance_template(template_name, project=project, **item)
            print("Created instance template {}".format(template_name))

            # Create instance groups with the new template.
            kwargs = {
                "project": project,
                "base_instance_name": instance_group_name,
                "size": count,
                "template": template_name,
            }
            if zone:
                kwargs["zone"] = zone
            elif region:
                kwargs["region"] = region
            if health_check:
                kwargs["health_check"] = health_check
            if initial_delay:
                kwargs["initial_delay"] = initial_delay
            gcloud.create_instance_group(instance_group_name, **kwargs)
            print("Created instance group {}".format(instance_group_name))
        finally:
            WORK_QUEUE.task_done()


def read_config_file():
    path = os.path.join(os.getcwd(), "instances.yml")
    with open(path, "rb") as fd:
        content = fd.read().decode("utf-8")
    return yaml.safe_load(content)


def main(argv=None):
    if argv is None:
        argv = sys.argv[1:]

    parser = argparse.ArgumentParser(description="Bazel CI Instance Creation")
    parser.add_argument(
        "names",
        type=str,
        nargs="*",
        help="List of instance (group) names that should be created. "
        'These values must correspond to "name" entries in the '
        'Yaml configuration, e.g. "bk-pipeline-ubuntu1804-java8".',
    )

    args = parser.parse_args(argv)
    config = read_config_file()

    # Verify names passed on the command-line.
    valid_names = [item["name"] for item in config["instance_groups"]]
    for name in args.names:
        if name not in valid_names:
            print("Unknown instance name: {}!".format(name))
            print("\nValid instance names are: {}".format(" ".join(valid_names)))
            return 1
    if not args.names:
        parser.print_help()
        print("\nValid instance names are: {}".format(" ".join(valid_names)))
        return 1

    # Put VM creation instructions into the work queue.
    for instance in config["instance_groups"]:
        if instance["name"] not in args.names:
            continue
        WORK_QUEUE.put({**config["default_vm"], **instance})

    # Spawn worker threads that will create the VMs.
    threads = []
    for _ in range(WORK_QUEUE.qsize()):
        t = threading.Thread(target=worker)
        t.start()
        threads.append(t)

    # Wait for all VMs to be created.
    WORK_QUEUE.join()

    # Signal worker threads to exit.
    for _ in range(len(threads)):
        WORK_QUEUE.put(None)

    # Wait for worker threads to exit.
    for t in threads:
        t.join()

    return 0


if __name__ == "__main__":
    sys.exit(main())
