// Copyright 2018 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 deprecated

import (
	"encoding/json"
	"strconv"
	"strings"

	"go.chromium.org/luci/buildbucket/protoutil"
	"go.chromium.org/luci/common/api/swarming/swarming/v1"
	"go.chromium.org/luci/common/data/strpair"
	"go.chromium.org/luci/common/errors"

	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/structpb"
	"google.golang.org/protobuf/types/known/timestamppb"

	pb "go.chromium.org/luci/buildbucket/proto"
	v1 "go.chromium.org/luci/common/api/buildbucket/buildbucket/v1"
)

// This file implements v1<->v2 interoperation.

// malformedBuild tag is present in an error if the build was malformed.
var malformedBuild = errors.BoolTag{Key: errors.NewTagKey("malformed buildbucket v1 build")}

// statusToV2 converts v1 build's Status, Result, FailureReason and
// CancelationReason to v2 Status enum.
//
// If build.Status is "", returns (Status_STATUS_UNSPECIFIED, nil).
// Useful with partial buildbucket responses.
func statusToV2(build *v1.LegacyApiCommonBuildMessage) (pb.Status, error) {
	switch build.Status {
	case "":
		return pb.Status_STATUS_UNSPECIFIED, nil

	case "SCHEDULED":
		return pb.Status_SCHEDULED, nil

	case "STARTED":
		return pb.Status_STARTED, nil

	case "COMPLETED":
		switch build.Result {
		case "SUCCESS":
			return pb.Status_SUCCESS, nil

		case "FAILURE":
			switch build.FailureReason {
			case "", "BUILD_FAILURE":
				return pb.Status_FAILURE, nil
			case "INFRA_FAILURE", "BUILDBUCKET_FAILURE", "INVALID_BUILD_DEFINITION":
				return pb.Status_INFRA_FAILURE, nil
			default:
				return 0, errors.Reason("unexpected failure reason %q", build.FailureReason).Tag(malformedBuild).Err()
			}

		case "CANCELED":
			switch build.CancelationReason {
			case "", "CANCELED_EXPLICITLY":
				return pb.Status_CANCELED, nil
			case "TIMEOUT":
				return pb.Status_INFRA_FAILURE, nil
			default:
				return 0, errors.Reason("unexpected cancellation reason %q", build.CancelationReason).Tag(malformedBuild).Err()
			}

		default:
			return 0, errors.Reason("unexpected result %q", build.Result).Tag(malformedBuild).Err()
		}

	default:
		return 0, errors.Reason("unexpected status %q", build.Status).Tag(malformedBuild).Err()
	}
}

type v1Params struct {
	Builder    string          `json:"builder_name"`
	Properties json.RawMessage `json:"properties"`
}

// BuildToV2 converts a v1 build message to v2.
//
// The returned build may be incomplete if msg is incomplete.
// For example, if msg is a partial response and does not have builder name,
// the returned build won't have it either.
//
// The returned build does not include steps.
// Returns an error if msg is malformed.
func BuildToV2(msg *v1.LegacyApiCommonBuildMessage) (b *pb.Build, err error) {
	// This implementation is a port of
	// https://chromium.googlesource.com/infra/infra/+/d55f587c0f30b0297e4d134c698e7458baa39b7f/appengine/cr-buildbucket/v2/builds.py#21

	params := &v1Params{}
	if msg.ParametersJson != "" {
		if err = json.NewDecoder(strings.NewReader(msg.ParametersJson)).Decode(params); err != nil {
			return nil, errors.Annotate(err, "ParametersJson is invalid").Tag(malformedBuild).Err()
		}
	}

	resultDetails := &struct {
		Properties json.RawMessage                 `json:"properties"`
		TaskResult swarming.SwarmingRpcsTaskResult `json:"task_result"`
		UI         struct {
			Info string `json:"info"`
		} `json:"ui"`
	}{}
	if msg.ResultDetailsJson != "" {
		if err = json.NewDecoder(strings.NewReader(msg.ResultDetailsJson)).Decode(resultDetails); err != nil {
			return nil, errors.Annotate(err, "ResultDetailsJson is invalid").Tag(malformedBuild).Err()
		}
	}

	tags := strpair.ParseMap(msg.Tags)
	address := tags.Get(v1.TagBuildAddress)
	var number int
	if address != "" {
		_, _, _, _, number, err = v1.ParseBuildAddress(address)
		if err != nil {
			return nil, errors.Annotate(err, "invalid build address %q", address).Tag(malformedBuild).Err()
		}
	}

	status, err := statusToV2(msg)
	if err != nil {
		return nil, err
	}

	builder, err := builderToV2(msg, tags, params)
	if err != nil {
		return nil, err
	}

	b = &pb.Build{
		Id:        msg.Id,
		Builder:   builder,
		Number:    int32(number),
		CreatedBy: msg.CreatedBy,

		CreateTime: timestampToV2(msg.CreatedTs),
		StartTime:  timestampToV2(msg.StartedTs),
		EndTime:    timestampToV2(msg.CompletedTs),
		UpdateTime: timestampToV2(msg.UpdatedTs),

		Status:          status,
		SummaryMarkdown: resultDetails.UI.Info,
		Canary:          msg.Canary,

		Input: &pb.Build_Input{
			Experimental: msg.Experimental,
		},
		Output: &pb.Build_Output{},

		Infra: &pb.BuildInfra{
			Buildbucket: &pb.BuildInfra_Buildbucket{},
			Swarming: &pb.BuildInfra_Swarming{
				Hostname:           tags.Get("swarming_hostname"),
				TaskId:             tags.Get("swarming_task_id"),
				TaskServiceAccount: msg.ServiceAccount,
			},
		},
	}

	if b.Input.Properties, err = propertiesToV2(params.Properties); err != nil {
		return nil, errors.Annotate(err, "invalid input properties").Tag(malformedBuild).Err()
	}
	if b.Output.Properties, err = propertiesToV2(resultDetails.Properties); err != nil {
		return nil, errors.Annotate(err, "invalid output properties").Tag(malformedBuild).Err()
	}

	b.Infra.Swarming.BotDimensions = make([]*pb.StringPair, 0, len(resultDetails.TaskResult.BotDimensions))
	for _, d := range resultDetails.TaskResult.BotDimensions {
		for _, v := range d.Value {
			b.Infra.Swarming.BotDimensions = append(b.Infra.Swarming.BotDimensions, &pb.StringPair{
				Key:   d.Key,
				Value: v,
			})
		}
	}

	if err := tagsToV2(b, msg.Tags); err != nil {
		return nil, err
	}
	return b, nil
}

func tagsToV2(dest *pb.Build, tags []string) error {
	dest.Input.GitilesCommit = nil
	for _, t := range toStringPairs(tags) {
		switch t.Key {
		case v1.TagBuilder, v1.TagBuildAddress:
			// We've already parsed these tags.

		case v1.TagBuildSet:
			switch bs := protoutil.ParseBuildSet(t.Value).(type) {
			case *pb.GerritChange:
				dest.Input.GerritChanges = append(dest.Input.GerritChanges, bs)
			case *pb.GitilesCommit:
				if dest.Input.GitilesCommit != nil {
					return errors.Reason("more than one gitiles commit buildset").Tag(malformedBuild).Err()
				}
				dest.Input.GitilesCommit = bs
			default:
				dest.Tags = append(dest.Tags, t)
			}

		case "swarming_dimension":
			if d := toStringPair(t.Value); d != nil {
				dest.Infra.Swarming.TaskDimensions = append(dest.Infra.Swarming.TaskDimensions, &pb.RequestedDimension{
					Key:   d.Key,
					Value: d.Value,
				})
			}

		case "swarming_tag":
			if st := toStringPair(t.Value); st != nil {
				switch st.Key {
				case "priority":
					pri, _ := strconv.ParseInt(st.Value, 10, 32)
					dest.Infra.Swarming.Priority = int32(pri)
				case "buildbucket_template_revision":
					dest.Infra.Buildbucket.ServiceConfigRevision = st.Value
				}
			}

		default:
			dest.Tags = append(dest.Tags, t)
		}
	}
	return nil
}

// BucketNameToV2 converts a v1 Bucket name to the v2 constituent parts.
// An error is returned if the bucketname does not match the expected format.
// The difference between the bucket name is that v2 uses short names, for example:
// v1: luci.chromium.try
// v2: try
// "luci" is dropped, "chromium" is recorded as the project, "try" is the name.
// If the bucket does not conform to this convention, or if it is not a luci bucket,
// then this return and empty string for both project and bucket.
func BucketNameToV2(v1Bucket string) (project string, bucket string) {
	p := strings.SplitN(v1Bucket, ".", 3)
	if len(p) != 3 || p[0] != "luci" {
		return "", ""
	}
	return p[1], p[2]
}

// builderToV2 attempts to parse as many fields into bucket and project as possible,
// and do project name validation if the project is available.
func builderToV2(msg *v1.LegacyApiCommonBuildMessage, tags strpair.Map, params *v1Params) (ret *pb.BuilderID, err error) {
	ret = &pb.BuilderID{Builder: params.Builder}
	if ret.Builder == "" {
		ret.Builder = tags.Get(v1.TagBuilder) // Fallback: Grab builder name from tags.
	}

	ret.Project, ret.Bucket = BucketNameToV2(msg.Bucket)
	if msg.Project != "" && ret.Project != "" && ret.Project != msg.Project {
		err = errors.Reason(
			"message project %q does not match bucket project %q", msg.Project, ret.Project).Tag(malformedBuild).Err()
	}
	return
}

func timestampToV2(ts int64) *timestamppb.Timestamp {
	if ts == 0 {
		return nil
	}
	ret := timestamppb.New(v1.ParseTimestamp(ts))
	return ret
}

func propertiesToV2(v1 json.RawMessage) (*structpb.Struct, error) {
	if len(v1) == 0 {
		return nil, nil
	}
	ret := &structpb.Struct{}
	return ret, protojson.Unmarshal([]byte(string(v1)), ret)
}

func toStringPair(s string) *pb.StringPair {
	parts := strings.SplitN(s, ":", 2)
	if len(parts) != 2 {
		return nil
	}
	return &pb.StringPair{Key: parts[0], Value: parts[1]}
}

func toStringPairs(tags []string) []*pb.StringPair {
	ret := make([]*pb.StringPair, 0, len(tags))
	for _, t := range tags {
		if p := toStringPair(t); p != nil {
			ret = append(ret, p)
		}
	}
	return ret
}
