// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package common

import (
	"context"
	"fmt"
	"log"
	"sort"
	"time"

	"dawn.googlesource.com/dawn/tools/src/buildbucket"
	"dawn.googlesource.com/dawn/tools/src/gerrit"
)

// BuildsByName is a map of builder name to build result
type BuildsByName map[string]buildbucket.Build

func (b BuildsByName) ids() []buildbucket.BuildID {
	ids := make([]buildbucket.BuildID, 0, len(b))
	for _, build := range b {
		ids = append(ids, build.ID)
	}
	return ids
}

// GetBuilds returns the builds, as declared in the config file, for the given
// patchset
func GetBuilds(
	ctx context.Context,
	cfg Config,
	ps gerrit.Patchset,
	bb *buildbucket.Buildbucket) (BuildsByName, error) {

	builds := BuildsByName{}

	err := bb.SearchBuilds(ctx, ps, func(build buildbucket.Build) error {
		for name, builder := range cfg.Builders {
			if build.Builder == builder {
				builds[name] = build
				break
			}
		}
		return nil
	})
	if err != nil {
		return nil, err
	}

	return builds, err
}

// WaitForBuildsToComplete waits until all the provided builds have finished.
func WaitForBuildsToComplete(
	ctx context.Context,
	cfg Config,
	ps gerrit.Patchset,
	bb *buildbucket.Buildbucket,
	builds BuildsByName) error {

	buildsStillRunning := func() []string {
		out := []string{}
		for name, build := range builds {
			if build.Status.Running() {
				out = append(out, name)
			}
		}
		sort.Strings(out)
		return out
	}

	for {
		// Refresh build status
		for name, build := range builds {
			build, err := bb.QueryBuild(ctx, build.ID)
			if err != nil {
				return fmt.Errorf("failed to query build for '%v': %w", name, err)
			}
			builds[name] = build
		}
		running := buildsStillRunning()
		if len(running) == 0 {
			break
		}
		log.Println("waiting for builds to complete: ", running)
		time.Sleep(time.Minute * 2)
	}

	for name, build := range builds {
		if build.Status == buildbucket.StatusInfraFailure ||
			build.Status == buildbucket.StatusCanceled {
			return fmt.Errorf("%v builder failed with %v", name, build.Status)
		}
	}

	return nil
}

// GetOrStartBuildsAndWait starts the builds as declared in the config file,
// for the given patchset, if they haven't already been started or if retest is
// true. GetOrStartBuildsAndWait then waits for the builds to complete, and then
// returns the results.
func GetOrStartBuildsAndWait(
	ctx context.Context,
	cfg Config,
	ps gerrit.Patchset,
	bb *buildbucket.Buildbucket,
	parentSwarmingRunId string,
	retest bool) (BuildsByName, error) {

	builds := BuildsByName{}

	if !retest {
		// Find any existing builds for the patchset
		err := bb.SearchBuilds(ctx, ps, func(build buildbucket.Build) error {
			for name, builder := range cfg.Builders {
				if build.Builder == builder {
					builds[name] = build
					break
				}
			}
			return nil
		})
		if err != nil {
			return nil, err
		}
	}

	// Returns true if the build should be re-kicked
	shouldKick := func(build buildbucket.Build) bool {
		switch build.Status {
		case buildbucket.StatusUnknown,
			buildbucket.StatusInfraFailure,
			buildbucket.StatusCanceled:
			return true
		}
		return false
	}

	// Kick any missing builds
	for name, builder := range cfg.Builders {
		if build, found := builds[name]; !found || shouldKick(build) {
			build, err := bb.StartBuild(ctx, ps, builder, parentSwarmingRunId, retest)
			if err != nil {
				return nil, err
			}
			log.Printf("started build: %+v\nLogs at: https://ci.chromium.org/ui/b/%v", build, build.ID)
			builds[name] = build
		}
	}

	if err := WaitForBuildsToComplete(ctx, cfg, ps, bb, builds); err != nil {
		return nil, err
	}

	return builds, nil
}
