// 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 service

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 ResultStore Upload API. See
// https://github.com/googleapis/googleapis/tree/master/google/devtools/resultstore/v2 for
// more details on the proto and gRPC libraries.
//
// Service methods generate UUIDs for certain proto.Message fields.  If the provided
// Context contains a non-empty string value for TestUUIDContextKey, that value will be
// used instead.
//
// Service methods require an Invocation's auth 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
}

// New creates a new Service.  Set useFakeUUIDs to true to use fake UUIDs for
// testing.  authToken is the authorization token to use for the invocation.  The same
// token must be used in all requests to modify a single invocation.
func New(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 TestUUIDContextKey, that value will be used instead. If
// there was an error when reading the UUID from the context, a message is logged
// describing the error 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:       s.uuid(ctx),
		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
}

// UpdateTestAction updates the duration and status of a previously started TestAction.
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
}

// UpdateConfiguredTarget updates the duration and status of a previously started
// UpdateConfigured.
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
}

// UpdateTarget updates the duration and status of a previously started Target.
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
}

// UpdateInvocation updates the duration and status of a previously started Invocation.
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
}

// FinishConfiguredTarget closes a ConfiguredTarget for editing.
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
}

// FinishTarget closes a Target for editing.
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
}

// FinishInvocation closes an Invocation for editing.
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
}
