package metadata // import "github.com/docker/docker/distribution/metadata"

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/layer"
	"github.com/opencontainers/go-digest"
)

// V2MetadataService maps layer IDs to a set of known metadata for
// the layer.
type V2MetadataService interface {
	GetMetadata(diffID layer.DiffID) ([]V2Metadata, error)
	GetDiffID(dgst digest.Digest) (layer.DiffID, error)
	Add(diffID layer.DiffID, metadata V2Metadata) error
	TagAndAdd(diffID layer.DiffID, hmacKey []byte, metadata V2Metadata) error
	Remove(metadata V2Metadata) error
}

// v2MetadataService implements V2MetadataService
type v2MetadataService struct {
	store Store
}

var _ V2MetadataService = &v2MetadataService{}

// V2Metadata contains the digest and source repository information for a layer.
type V2Metadata struct {
	Digest           digest.Digest
	SourceRepository string
	// HMAC hashes above attributes with recent authconfig digest used as a key in order to determine matching
	// metadata entries accompanied by the same credentials without actually exposing them.
	HMAC string
}

// CheckV2MetadataHMAC returns true if the given "meta" is tagged with a hmac hashed by the given "key".
func CheckV2MetadataHMAC(meta *V2Metadata, key []byte) bool {
	if len(meta.HMAC) == 0 || len(key) == 0 {
		return len(meta.HMAC) == 0 && len(key) == 0
	}
	mac := hmac.New(sha256.New, key)
	mac.Write([]byte(meta.Digest))
	mac.Write([]byte(meta.SourceRepository))
	expectedMac := mac.Sum(nil)

	storedMac, err := hex.DecodeString(meta.HMAC)
	if err != nil {
		return false
	}

	return hmac.Equal(storedMac, expectedMac)
}

// ComputeV2MetadataHMAC returns a hmac for the given "meta" hash by the given key.
func ComputeV2MetadataHMAC(key []byte, meta *V2Metadata) string {
	if len(key) == 0 || meta == nil {
		return ""
	}
	mac := hmac.New(sha256.New, key)
	mac.Write([]byte(meta.Digest))
	mac.Write([]byte(meta.SourceRepository))
	return hex.EncodeToString(mac.Sum(nil))
}

// ComputeV2MetadataHMACKey returns a key for the given "authConfig" that can be used to hash v2 metadata
// entries.
func ComputeV2MetadataHMACKey(authConfig *types.AuthConfig) ([]byte, error) {
	if authConfig == nil {
		return nil, nil
	}
	key := authConfigKeyInput{
		Username:      authConfig.Username,
		Password:      authConfig.Password,
		Auth:          authConfig.Auth,
		IdentityToken: authConfig.IdentityToken,
		RegistryToken: authConfig.RegistryToken,
	}
	buf, err := json.Marshal(&key)
	if err != nil {
		return nil, err
	}
	return []byte(digest.FromBytes(buf)), nil
}

// authConfigKeyInput is a reduced AuthConfig structure holding just relevant credential data eligible for
// hmac key creation.
type authConfigKeyInput struct {
	Username string `json:"username,omitempty"`
	Password string `json:"password,omitempty"`
	Auth     string `json:"auth,omitempty"`

	IdentityToken string `json:"identitytoken,omitempty"`
	RegistryToken string `json:"registrytoken,omitempty"`
}

// maxMetadata is the number of metadata entries to keep per layer DiffID.
const maxMetadata = 50

// NewV2MetadataService creates a new diff ID to v2 metadata mapping service.
func NewV2MetadataService(store Store) V2MetadataService {
	return &v2MetadataService{
		store: store,
	}
}

func (serv *v2MetadataService) diffIDNamespace() string {
	return "v2metadata-by-diffid"
}

func (serv *v2MetadataService) digestNamespace() string {
	return "diffid-by-digest"
}

func (serv *v2MetadataService) diffIDKey(diffID layer.DiffID) string {
	return string(digest.Digest(diffID).Algorithm()) + "/" + digest.Digest(diffID).Hex()
}

func (serv *v2MetadataService) digestKey(dgst digest.Digest) string {
	return string(dgst.Algorithm()) + "/" + dgst.Hex()
}

// GetMetadata finds the metadata associated with a layer DiffID.
func (serv *v2MetadataService) GetMetadata(diffID layer.DiffID) ([]V2Metadata, error) {
	if serv.store == nil {
		return nil, errors.New("no metadata storage")
	}
	jsonBytes, err := serv.store.Get(serv.diffIDNamespace(), serv.diffIDKey(diffID))
	if err != nil {
		return nil, err
	}

	var metadata []V2Metadata
	if err := json.Unmarshal(jsonBytes, &metadata); err != nil {
		return nil, err
	}

	return metadata, nil
}

// GetDiffID finds a layer DiffID from a digest.
func (serv *v2MetadataService) GetDiffID(dgst digest.Digest) (layer.DiffID, error) {
	if serv.store == nil {
		return layer.DiffID(""), errors.New("no metadata storage")
	}
	diffIDBytes, err := serv.store.Get(serv.digestNamespace(), serv.digestKey(dgst))
	if err != nil {
		return layer.DiffID(""), err
	}

	return layer.DiffID(diffIDBytes), nil
}

// Add associates metadata with a layer DiffID. If too many metadata entries are
// present, the oldest one is dropped.
func (serv *v2MetadataService) Add(diffID layer.DiffID, metadata V2Metadata) error {
	if serv.store == nil {
		// Support a service which has no backend storage, in this case
		// an add becomes a no-op.
		// TODO: implement in memory storage
		return nil
	}
	oldMetadata, err := serv.GetMetadata(diffID)
	if err != nil {
		oldMetadata = nil
	}
	newMetadata := make([]V2Metadata, 0, len(oldMetadata)+1)

	// Copy all other metadata to new slice
	for _, oldMeta := range oldMetadata {
		if oldMeta != metadata {
			newMetadata = append(newMetadata, oldMeta)
		}
	}

	newMetadata = append(newMetadata, metadata)

	if len(newMetadata) > maxMetadata {
		newMetadata = newMetadata[len(newMetadata)-maxMetadata:]
	}

	jsonBytes, err := json.Marshal(newMetadata)
	if err != nil {
		return err
	}

	err = serv.store.Set(serv.diffIDNamespace(), serv.diffIDKey(diffID), jsonBytes)
	if err != nil {
		return err
	}

	return serv.store.Set(serv.digestNamespace(), serv.digestKey(metadata.Digest), []byte(diffID))
}

// TagAndAdd amends the given "meta" for hmac hashed by the given "hmacKey" and associates it with a layer
// DiffID. If too many metadata entries are present, the oldest one is dropped.
func (serv *v2MetadataService) TagAndAdd(diffID layer.DiffID, hmacKey []byte, meta V2Metadata) error {
	meta.HMAC = ComputeV2MetadataHMAC(hmacKey, &meta)
	return serv.Add(diffID, meta)
}

// Remove disassociates a metadata entry from a layer DiffID.
func (serv *v2MetadataService) Remove(metadata V2Metadata) error {
	if serv.store == nil {
		// Support a service which has no backend storage, in this case
		// an remove becomes a no-op.
		// TODO: implement in memory storage
		return nil
	}
	diffID, err := serv.GetDiffID(metadata.Digest)
	if err != nil {
		return err
	}
	oldMetadata, err := serv.GetMetadata(diffID)
	if err != nil {
		oldMetadata = nil
	}
	newMetadata := make([]V2Metadata, 0, len(oldMetadata))

	// Copy all other metadata to new slice
	for _, oldMeta := range oldMetadata {
		if oldMeta != metadata {
			newMetadata = append(newMetadata, oldMeta)
		}
	}

	if len(newMetadata) == 0 {
		return serv.store.Delete(serv.diffIDNamespace(), serv.diffIDKey(diffID))
	}

	jsonBytes, err := json.Marshal(newMetadata)
	if err != nil {
		return err
	}

	return serv.store.Set(serv.diffIDNamespace(), serv.diffIDKey(diffID), jsonBytes)
}
