// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package resultstore

import (
	"context"
	"log"

	"github.com/google/uuid"
	api "google.golang.org/genproto/googleapis/devtools/resultstore/v2"
	"google.golang.org/genproto/protobuf/field_mask"
)

// Service implements the ResultStoreUpload gRPC service.
//
// Service generates UUIDs for each request sent to Resultstore. If the provided
// Context object contains a non-empty string value for TestUUIDKey, that value is
// used instead. This is done by calling `SetTestUUID(ctx, "uuid")`.
//
// Service requires an Invocation's authorization token to be set in the provided Context.
// This can be done by calling: `SetAuthToken(ctx, "auth-token")`.
type Service interface {
	// CreateInvocation creates an Invocation in ResultStore. This must be called before
	// any other "Create" methods, since all resources belong to an Invocation.
	CreateInvocation(context.Context, *Invocation) (*Invocation, error)

	// CreateConfiguration creates a new Configuration. Configurations typically represent
	// build or test environments.
	CreateConfiguration(context.Context, *Configuration, string) (*Configuration, error)

	// CreateTarget creates a new build or test target for the Invocation with the given
	// name.
	CreateTarget(context.Context, *Target, string) (*Target, error)

	// CreateConfiguredTarget creates a new ConfiguredTarget for the Target with the given
	// name. ConfiguredTargets represent targets executing with a specific Configuration.
	CreateConfiguredTarget(context.Context, *ConfiguredTarget, string) (*ConfiguredTarget, error)

	// CreateTestAction creates a new Action for the ConfiguredTarget with the given name.
	CreateTestAction(context.Context, *TestAction, string) (*TestAction, error)

	// UpdateTestAction patches the start time, duration and status of a TestAction.
	UpdateTestAction(context.Context, *TestAction) (*TestAction, error)

	// UpdateConfiguredTarget patches the start time, duration and status of a
	// ConfiguredTarget.
	UpdateConfiguredTarget(context.Context, *ConfiguredTarget) (*ConfiguredTarget, error)

	// UpdateTarget patches the start time, duration and status of a Target.
	UpdateTarget(context.Context, *Target) (*Target, error)

	// UpdateTarget patches the start time, duration and status of a Target.
	UpdateInvocation(context.Context, *Invocation) (*Invocation, error)

	// FinishConfiguredTarget closes a ConfiguredTarget for editing.
	FinishConfiguredTarget(context.Context, string) error

	// FinishTarget closes a Target for editing.
	FinishTarget(context.Context, string) error

	// FinishInvocation closes an Invocation for editing.
	FinishInvocation(context.Context, string) error
}

// NewService creates a new Service. This is visible for testing; Use `Connect` instead.
func NewService(client api.ResultStoreUploadClient) Service {
	return &service{client: client}
}

// The default Service implementation.
type service struct {
	client api.ResultStoreUploadClient
}

// uuid generates an RFC-4122 compliant Version 4 UUID.  If the provided Context contains
// a non-empty string value for TestUUIDKey, that value will be used instead. If there was
// an error when reading the UUID from the context, a message describing the error is
// logged and a new UUID is generated.
func (s *service) uuid(ctx context.Context) string {
	value, err := TestUUID(ctx)

	if err != nil {
		log.Println(err)
		return uuid.New().String()
	}

	if value == "" {
		return uuid.New().String()
	}

	return value
}

func (s *service) CreateInvocation(ctx context.Context, invocation *Invocation) (*Invocation, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.CreateInvocation(ctx, &api.CreateInvocationRequest{
		RequestId:          s.uuid(ctx),
		AuthorizationToken: authToken,
		InvocationId:       invocation.ID,
		Invocation:         invocation.ToResultStoreInvocation(),
	})
	if err != nil {
		return nil, err
	}

	output := new(Invocation)
	output.FromResultStoreInvocation(res)
	return output, nil
}

func (s *service) CreateConfiguration(ctx context.Context, config *Configuration, invocationName string) (*Configuration, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.CreateConfiguration(ctx, &api.CreateConfigurationRequest{
		RequestId:          s.uuid(ctx),
		AuthorizationToken: authToken,
		Parent:             invocationName,
		ConfigId:           config.ID,
		Configuration:      config.ToResultStoreConfiguration(),
	})
	if err != nil {
		return nil, err
	}

	output := new(Configuration)
	output.FromResultStoreConfiguration(res)
	return output, nil
}

func (s *service) CreateTarget(ctx context.Context, target *Target, invocationName string) (*Target, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.CreateTarget(ctx, &api.CreateTargetRequest{
		RequestId:          s.uuid(ctx),
		AuthorizationToken: authToken,
		Parent:             invocationName,
		TargetId:           target.ID,
		Target:             target.ToResultStoreTarget(),
	})
	if err != nil {
		return nil, err
	}

	output := new(Target)
	output.FromResultStoreTarget(res)
	return output, nil
}

func (s *service) CreateConfiguredTarget(ctx context.Context, configTarget *ConfiguredTarget, targetName string) (*ConfiguredTarget, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.CreateConfiguredTarget(ctx, &api.CreateConfiguredTargetRequest{
		AuthorizationToken: authToken,
		RequestId:          s.uuid(ctx),
		Parent:             targetName,
		ConfigId:           configTarget.ConfigID,
		ConfiguredTarget:   configTarget.ToResultStoreConfiguredTarget(),
	})
	if err != nil {
		return nil, err
	}

	output := new(ConfiguredTarget)
	output.FromResultStoreConfiguredTarget(res)
	return output, nil
}

func (s *service) CreateTestAction(ctx context.Context, action *TestAction, configTargetName string) (*TestAction, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.CreateAction(ctx, &api.CreateActionRequest{
		AuthorizationToken: authToken,
		RequestId:          s.uuid(ctx),
		Parent:             configTargetName,
		ActionId:           action.ID,
		Action:             action.ToResultStoreAction(),
	})
	if err != nil {
		return nil, err
	}

	output := new(TestAction)
	output.FromResultStoreAction(res)
	return output, nil
}

func (s *service) UpdateTestAction(ctx context.Context, action *TestAction) (*TestAction, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.UpdateAction(ctx, &api.UpdateActionRequest{
		AuthorizationToken: authToken,
		Action:             action.ToResultStoreAction(),
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"timing.duration", "status_attributes"},
		},
	})
	if err != nil {
		return nil, err
	}

	output := new(TestAction)
	output.FromResultStoreAction(res)
	return output, nil
}

func (s *service) UpdateConfiguredTarget(ctx context.Context, configTarget *ConfiguredTarget) (*ConfiguredTarget, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.UpdateConfiguredTarget(ctx, &api.UpdateConfiguredTargetRequest{
		AuthorizationToken: authToken,
		ConfiguredTarget:   configTarget.ToResultStoreConfiguredTarget(),
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"timing.duration", "status_attributes"},
		},
	})
	if err != nil {
		return nil, err
	}

	output := new(ConfiguredTarget)
	output.FromResultStoreConfiguredTarget(res)
	return output, nil
}

func (s *service) UpdateTarget(ctx context.Context, target *Target) (*Target, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.UpdateTarget(ctx, &api.UpdateTargetRequest{
		AuthorizationToken: authToken,
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"timing.duration", "status_attributes"},
		},
		Target: target.ToResultStoreTarget(),
	})
	if err != nil {
		return nil, err
	}

	output := new(Target)
	output.FromResultStoreTarget(res)
	return output, nil
}

func (s *service) UpdateInvocation(ctx context.Context, invocation *Invocation) (*Invocation, error) {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return nil, err
	}

	res, err := s.client.UpdateInvocation(ctx, &api.UpdateInvocationRequest{
		AuthorizationToken: authToken,
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"timing.duration", "status_attributes"},
		},
		Invocation: invocation.ToResultStoreInvocation(),
	})
	if err != nil {
		return nil, err
	}

	output := new(Invocation)
	output.FromResultStoreInvocation(res)
	return output, nil
}

func (s *service) FinishConfiguredTarget(ctx context.Context, name string) error {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return err
	}

	_, err = s.client.FinishConfiguredTarget(ctx, &api.FinishConfiguredTargetRequest{
		AuthorizationToken: authToken,
		Name:               name,
	})
	return err
}

func (s *service) FinishTarget(ctx context.Context, name string) error {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return err
	}

	_, err = s.client.FinishTarget(ctx, &api.FinishTargetRequest{
		AuthorizationToken: authToken,
		Name:               name,
	})
	return err
}

func (s *service) FinishInvocation(ctx context.Context, name string) error {
	authToken, err := AuthToken(ctx)
	if err != nil {
		return err
	}

	_, err = s.client.FinishInvocation(ctx, &api.FinishInvocationRequest{
		AuthorizationToken: authToken,
		Name:               name,
	})
	return err
}
