// 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 (
	"fmt"
)

// Context stores information necessary to create an Invocation. It is used to support
// tilo clients that use a distributed execution model, where multiple processes
// participate in creating, modifying, and finishing an Invocation.  This can be
// accomplished by serializing the Context as a JSON object and passing it to another
// process.
//
// When creating ResultStore entities, the name of the entity's parent must be provided
// for ResultStore to make the parent-child association.  The entity name is created by
// the ResultStore backend and returned from the UploadApi methods.  This cache is used to
// store those names as they are returned.
//
// All requests to modify an Invocation require an authorization token, which is specified
// when the Invocation is created. This cache also stores that token.
//
// Context getters return false if values are not present, or empty.  Setters return false
// when values are already set.  Attempting to ovewrite a value should always be
// considered a bug. For example: if the auth token is ovewritten, we can no longer upload
// to an invocation.  If an entity name is ovewritten, we can no longer associate children
// with that entity.
//
// Please do not add information to this interface unless it is necessary to support
// creating Invocations in a distributed manner.
type Context interface {
	// SetAuthToken stores the Invocation's auth token.
	SetAuthToken(string) bool

	// AuthToken is the Invocation's auth token.
	AuthToken() string

	// SetInvocationID Stores the name of the Invocation.
	SetInvocationID(id string) bool

	// SetInvocationName Stores the name of the Invocation.
	SetInvocationName(name string) bool

	// InvocationID is the Invocation's ID.
	InvocationID() string

	// InvocationName is the Invocation's name.
	InvocationName() string

	// SetTarget stores a Target's name under its ID.
	SetTarget(id, name string) bool

	// Target returns a Target's name, given its ID.
	Target(id string) string

	// SetConfiguredTarget stores a ConfiguredTarget's name under its ID.
	SetConfiguredTarget(targetID, configID string, name string) bool

	// ConfiguredTarget returns a ConfiguredTarget's name, given its ID.
	ConfiguredTarget(targetID, configID string) string
}

// NewContext returns a new Context.
func NewContext() Context {
	return &rsContext{}
}

// The default Context implementation.
type rsContext struct {
	AuthTokenValue        string            `json:"auth_token"`
	InvocationNameValue   string            `json:"invocation_name"`
	InvocationIDValue     string            `json:"invocation_id"`
	TargetNames           map[string]string `json:"targets"`
	ConfiguredTargetNames map[string]string `json:"configured_targets"`
}

func (c *rsContext) SetAuthToken(value string) bool {
	if c.AuthTokenValue != "" && c.AuthTokenValue != value {
		return false
	}
	c.AuthTokenValue = value
	return true
}

func (c *rsContext) AuthToken() string {
	return c.AuthTokenValue
}

func (c *rsContext) SetInvocationName(name string) bool {
	if c.InvocationNameValue != "" && c.InvocationNameValue != name {
		return false
	}
	c.InvocationNameValue = name
	return true
}

func (c *rsContext) InvocationName() string {
	return c.InvocationNameValue
}

func (c *rsContext) SetInvocationID(name string) bool {
	if c.InvocationIDValue != "" && c.InvocationIDValue != name {
		return false
	}
	c.InvocationIDValue = name
	return true
}

func (c *rsContext) InvocationID() string {
	return c.InvocationIDValue
}

func (c *rsContext) SetTarget(id, name string) bool {
	c.ensureTargets()
	oldName := c.Target(id)
	if oldName != "" && oldName != name {
		return false
	}

	c.TargetNames[id] = name
	return true
}

func (c *rsContext) Target(id string) string {
	c.ensureTargets()
	val, _ := c.TargetNames[id]
	return val
}

func (c *rsContext) SetConfiguredTarget(targetID, configID string, name string) bool {
	c.ensureConfiguredTargets()
	oldName := c.ConfiguredTarget(targetID, configID)
	if oldName != "" && oldName != name {
		return false
	}

	ID := c.createConfiguredTargetID(targetID, configID)
	c.ConfiguredTargetNames[ID] = name
	return true
}

func (c *rsContext) ConfiguredTarget(targetID, configID string) string {
	c.ensureConfiguredTargets()
	ID := c.createConfiguredTargetID(targetID, configID)
	val, _ := c.ConfiguredTargetNames[ID]
	return val
}

func (c *rsContext) ensureTargets() {
	if c.TargetNames == nil {
		c.TargetNames = make(map[string]string)
	}
}

func (c *rsContext) ensureConfiguredTargets() {
	if c.ConfiguredTargetNames == nil {
		c.ConfiguredTargetNames = make(map[string]string)
	}
}

func (c rsContext) createConfiguredTargetID(targetID, configID string) string {
	return fmt.Sprintf("(target=%s,config=%s)", targetID, configID)
}
