#!/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
import os
import sys
import yaml

import bazelci
from bazelci import BuildkiteException

# Buildkite has a max jobs limit at 2000, but that includes jobs already
# executed by the pipeline. Setting arbitrary lower number to make sure we fit
# under.
BUILDKITE_MAX_JOBS_LIMIT = 1500

BUILDKITE_ORG = os.environ["BUILDKITE_ORGANIZATION_SLUG"]

PIPELINE = "bazel-at-release-plus-incompatible-flags"


def get_failing_jobs(build_info):
    failing_jobs = []
    for job in build_info["jobs"]:
        if "state" in job and job["state"] == "failed":
            command = job["command"]
            if not command:
                bazelci.eprint("'command' field not found in the job: " + str(job))
                continue
            # Skip if the job is not a runner job
            if command.find("bazelci.py runner") == -1:
                continue

            # Get rid of the incompatible flags in the command line because we are going to test them individually
            command_without_incompatible_flags = " ".join(
                [i for i in command.split(" ") if not i.startswith("--incompatible_flag")]
            )

            # Recover the task name from job command
            flags = get_flags_from_command(command)
            task = flags.get("task")
            if not task:
                raise BuildkiteException(
                    "The following command has no --task argument: %s." % command
                )

            # Fetch the original job config to retrieve the platform name.
            job_config = bazelci.load_config(
                http_url=flags.get("http_config"), file_config=flags.get("file_config")
            )

            # The config can either contain a "tasks" dict (new format) or a "platforms" dict (legacy format).
            all_tasks = job_config.get("tasks", job_config.get("platforms"))
            if not all_tasks:
                raise BuildkiteException(
                    "Malformed configuration: No 'tasks' or 'platforms' entry found."
                )

            task_config = all_tasks.get(task)
            if not task_config:
                raise BuildkiteException(
                    "Configuration does not contain an entry for task '%s'" % task
                )

            # Shortcut: Users can skip the "platform" field if its value equals the task name.
            platform = task_config.get("platform") or task
            failing_jobs.append(
                {
                    "name": job["name"],
                    "command": command_without_incompatible_flags.split("\n"),
                    "platform": platform,
                }
            )
    return failing_jobs


def get_flags_from_command(command):
    flags = {}
    for entry in command.split(" "):
        if entry.startswith("--") and "=" in entry:
            key, _, value = entry[2:].partition("=")
            flags[key] = value

    return flags


def print_steps_for_failing_jobs(build_info):
    failing_jobs = get_failing_jobs(build_info)
    incompatible_flags = list(bazelci.fetch_incompatible_flags().keys())
    pipeline_steps = []
    counter = 0
    for incompatible_flag in incompatible_flags:
        for job in failing_jobs:
            counter += 1
            if counter > BUILDKITE_MAX_JOBS_LIMIT:
                continue
            label = "%s: %s" % (incompatible_flag, job["name"])
            command = list(job["command"])
            command[1] = command[1] + " --incompatible_flag=" + incompatible_flag
            pipeline_steps.append(bazelci.create_step(label, command, job["platform"]))
    if counter > BUILDKITE_MAX_JOBS_LIMIT:
        bazelci.eprint(
            "We only allow "
            + str(BUILDKITE_MAX_JOBS_LIMIT)
            + " jobs to be registered at once, skipping "
            + str(counter - BUILDKITE_MAX_JOBS_LIMIT)
            + " jobs."
        )
    print(yaml.dump({"steps": pipeline_steps}))


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

    parser = argparse.ArgumentParser(
        description="Script for testing failing jobs with individual incompatible flag"
    )
    parser.add_argument("--build_number", type=str)

    args = parser.parse_args(argv)
    try:
        if args.build_number:
            client = bazelci.BuildkiteClient(org=BUILDKITE_ORG, pipeline=PIPELINE)
            build_info = client.get_build_info(args.build_number)
            print_steps_for_failing_jobs(build_info)
        else:
            parser.print_help()
            return 2

    except BuildkiteException as e:
        bazelci.eprint(str(e))
        return 1
    return 0


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