// Copyright 2020 The LUCI Authors.
//
// 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.

package history

import (
	"context"
	"fmt"
	"testing"
	"time"

	"cloud.google.com/go/spanner"
	"google.golang.org/protobuf/types/known/timestamppb"

	"go.chromium.org/luci/common/clock/testclock"
	"go.chromium.org/luci/server/span"

	"go.chromium.org/luci/resultdb/internal/invocations"
	"go.chromium.org/luci/resultdb/internal/spanutil"
	"go.chromium.org/luci/resultdb/internal/testutil"
	"go.chromium.org/luci/resultdb/internal/testutil/insert"
	"go.chromium.org/luci/resultdb/pbutil"
	pb "go.chromium.org/luci/resultdb/proto/v1"
)

var useRedis = testutil.ConnectToRedis()

type benchmarkDataParams struct {
	nOSes, nVariants, nBuilds, nSteps, nShards, nTests, nResults int
}

func insertBenchmarkData(ctx context.Context, b *testing.B, p benchmarkDataParams) {
	start := testclock.TestRecentTimeUTC
	ms := make([]*spanner.Mutation, 0)
	for os := 0; os < p.nOSes; os++ {
		for v := 0; v < p.nVariants; v++ {
			builder := fmt.Sprintf("OS%d_Variant%d", os, v)
			for build := 0; build < p.nBuilds; build++ {
				buildInvID := invocations.ID(fmt.Sprintf("%s-build%d", builder, build))
				buildTS := start.Add(time.Duration(os*v) * time.Minute) // + build hours + ov minutes
				ms = append(ms, insert.Invocation(buildInvID, pb.Invocation_ACTIVE, map[string]interface{}{
					"HistoryTime": buildTS,
					"Realm":       "luci:benchmark",
				}))
				reachables := invocations.NewIDSet()
				for step := 0; step < p.nSteps; step++ {
					stepInvID := invocations.ID(fmt.Sprintf("%s-build%d-step%d", builder, build, step))
					ms = append(ms, insert.Invocation(stepInvID, pb.Invocation_ACTIVE, nil))
					ms = append(ms, insert.Inclusion(buildInvID, stepInvID))
					reachables.Add(stepInvID)
					for shard := 0; shard < p.nShards; shard++ {
						shardInvID := invocations.ID(fmt.Sprintf("%s-build%d-step%d-shard%d", builder, build, step, shard))
						ms = append(ms, insert.Invocation(shardInvID, pb.Invocation_ACTIVE, nil))
						ms = append(ms, insert.Inclusion(stepInvID, shardInvID))
						reachables.Add(shardInvID)
						for test := 0; test < p.nTests; test++ {
							testID := fmt.Sprintf("step%d-shard%d-test%d", step, shard, test)
							for result := 0; result < p.nResults; result++ {
								resultID := fmt.Sprint(result)
								ms = append(ms,
									spanutil.InsertMap("TestResults", map[string]interface{}{
										"InvocationId":    shardInvID,
										"TestId":          testID,
										"ResultId":        resultID,
										"Variant":         pbutil.Variant("os", fmt.Sprint(os), "variant", fmt.Sprint(v)),
										"VariantHash":     fmt.Sprintf("deadbeef%d%d", os, v),
										"CommitTimestamp": spanner.CommitTimestamp,
										"Status":          pb.TestStatus_PASS,
										"RunDurationUsec": 1534567,
									}))

							}
						}
					}
				}
				if useRedis {
					invocations.ReachCache(buildInvID).TryWrite(ctx, reachables)
				}

			}
		}
	}
	maxSpannerBatch := 2000
	for len(ms) > maxSpannerBatch {
		if _, err := span.Apply(ctx, ms[:maxSpannerBatch]); err != nil {
			b.Fatal(err)
		}
		ms = ms[maxSpannerBatch:]
	}

	if _, err := span.Apply(ctx, ms); err != nil {
		b.Fatal(err)
	}
}

func BenchmarkGetTestResultsHistory(b *testing.B) {
	runQueryBenchmark := func(ctx context.Context, b *testing.B, name string, q *Query, expectedResults int) {
		b.Run(name, func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				iCtx, cancel := span.ReadOnlyTransaction(ctx)
				r, _, err := q.Execute(iCtx)
				if err != nil {
					b.Fatal(err)
				}
				if len(r) != expectedResults {
					b.Fatal(fmt.Errorf("Expected %d results but got %d", expectedResults, len(r)))
				}
				cancel()
			}
		})
	}

	past := timestamppb.New(testclock.TestRecentTimeUTC)
	q := &Query{
		Request: &pb.GetTestResultHistoryRequest{
			Range: &pb.GetTestResultHistoryRequest_TimeRange{
				TimeRange: &pb.TimeRange{
					Earliest: past,
					Latest:   timestamppb.Now(),
				},
			},
			Realm: "luci:benchmark",
		},
		ignoreDeadline: true,
	}

	// 16 builders, each with 100 builds, where each build-level
	// invocation contains 20 sub-invocations (4 steps and 16 shards)
	// and 64 results (4 tests per shard, 1 result per test).
	p := benchmarkDataParams{4, 4, 100, 4, 4, 4, 1}
	ctx := testutil.SpannerTestContext(b)

	insertBenchmarkData(ctx, b, p)

	suffix := "-no-redis"
	if useRedis {
		suffix = "-local-redis"
	}

	q.Request.TestIdRegexp = "step0-shard0-test0"
	runQueryBenchmark(ctx, b, fmt.Sprintf("SpecificTest%s", suffix), q, 100)

	q.Request.VariantPredicate = &pb.VariantPredicate{
		Predicate: &pb.VariantPredicate_Contains{
			Contains: pbutil.Variant("os", "0", "variant", "0"),
		},
	}
	runQueryBenchmark(ctx, b, fmt.Sprintf("SpecificTestVariant%s", suffix), q, 100)
}
