// named is a utility for dealing with named fiddles.
package named

import (
	"errors"
	"fmt"
	"path/filepath"
	"regexp"
	"strings"

	"go.skia.org/infra/fiddlek/go/store"
	"go.skia.org/infra/go/sklog"
)

var (
	DuplicateNameErr = errors.New("Name already exists.")

	// fiddleHashRe is used to validate fiddle hashes.
	fiddleHashRe = regexp.MustCompile("^[0-9a-zA-Z]{32}$")

	// fiddlNameRe is used to validate fiddle names.
	fiddleNameRe = regexp.MustCompile("^[0-9a-zA-Z_]+$")

	// trailingToMedia maps the end of each image URL to the store.Media type
	// that it corresponds to.
	trailingToMedia = map[string]store.Media{
		"_raster.png": store.CPU,
		"_gpu.png":    store.GPU,
		".pdf":        store.PDF,
		".skp":        store.SKP,
		".txt":        store.TXT,
		"_cpu.webm":   store.ANIM_CPU,
		"_gpu.webm":   store.ANIM_GPU,
		"_glinfo.txt": store.GLINFO,
	}
)

// NameStore is an interface that store.Store conforms to that is just the
// methods that Named uses.
type NameStore interface {
	GetHashFromName(name string) (string, error)
	WriteName(name, hash, user, status string) error
}

// Named deals with creating and dereferencing named fiddles.
type Named struct {
	st NameStore
}

// New creates a new Named.
func New(st NameStore) *Named {
	return &Named{
		st: st,
	}
}

// Add a named fiddle.
//
//	name      - The name of the fidde, w/o the @ prefix.
//	hash      - The fiddle hash.
//	user      - The email of the user that created the name.
//	overwrite - True if the write should proceed if the name already exists.
func (n *Named) Add(name, hash, user string, overwrite bool) error {
	if !fiddleNameRe.MatchString(name) {
		return fmt.Errorf("Not a valid fiddle name %q", name)
	}
	if !fiddleHashRe.MatchString(hash) {
		return fmt.Errorf("Not a valid fiddle hash  %q", hash)
	}
	oldHash, err := n.DereferenceID("@" + name)
	if err == nil {
		// This name exists already.
		if !overwrite {
			return DuplicateNameErr
		}
		if oldHash == hash {
			// Don't bother writing if the hash is already correct.
			return nil
		}
		sklog.Infof("Named Fiddle Changed: %s %s -> %s by %s", name, oldHash, hash, user)
	} else {
		sklog.Infof("Named Fiddle Created: %s %s by %s", name, hash, user)
	}
	if err := n.st.WriteName(name, hash, user, ""); err != nil {
		return fmt.Errorf("Failed to write name: %s", err)
	}
	return nil
}

// Dereference converts the id to a fiddlehash, where id could
// be either a fiddle name or a fiddle hash. Fiddle names are
// presumed to be prefixed with "@".
//
// Returns an error if the fiddle hash is not valid looking.
func (n *Named) DereferenceID(id string) (string, error) {
	if len(id) < 2 {
		return "", fmt.Errorf("Invalid ID")
	}
	if id[0] == '@' {
		id = id[1:]
		// Look up the name in gs://skia-fiddle/named/<id>.
		var err error
		fiddleHash, err := n.st.GetHashFromName(id)
		if err != nil {
			return "", fmt.Errorf("Unknown name: %s", err)
		}
		if !fiddleHashRe.MatchString(fiddleHash) {
			return "", fmt.Errorf("Not a valid fiddle hash found in named file %q: %s", id, fiddleHash)
		}
		return fiddleHash, nil
	} else {
		// match against regex?
		if !fiddleHashRe.MatchString(id) {
			return "", fmt.Errorf("Not a valid fiddle hash: %q", id)
		}
		return id, nil
	}
}

// DereferenceImageID converts the id of an image to the fiddle hash and the
// Media it represents, handling both original fiddle hashes and fiddle names
// as part of the image id. Fiddle names are
// presumed to be prefixed with "@".
//
// I.e. it converts "cbb8dee39e9f1576cd97c2d504db8eee_gpu.png" to
// "cbb8dee39e9f1576cd97c2d504db8eee" and store.GPU.  and, could also convert
// "@star_raster.png" to "cbb8dee39e9f1576cd97c2d504db8eee" and store.CPU.
func (n *Named) DereferenceImageID(id string) (string, store.Media, error) {
	// First strip off the "_raster.png" or ".pdf" from the end.
	trailing := filepath.Ext(id)
	if len(trailing) < 4 {
		return "", store.UNKNOWN, fmt.Errorf("Not a valid image id: %q", id)
	}
	id = id[:len(id)-len(trailing)]
	// If this is a .png or .webm then we need to strip off the trailing "_raster" or "_gpu".
	if strings.HasSuffix(id, "_raster") || strings.HasSuffix(id, "_gpu") || strings.HasSuffix(id, "_cpu") || strings.HasSuffix(id, "_glinfo") {
		parts := strings.Split(id, "_")
		if len(parts) < 2 {
			return "", store.UNKNOWN, fmt.Errorf("Not a valid image id form: %q", id)
		}
		trailing = "_" + parts[len(parts)-1] + trailing
		id = strings.Join(parts[:len(parts)-1], "_")
	}
	media, ok := trailingToMedia[trailing]
	if !ok {
		return "", store.UNKNOWN, fmt.Errorf("Unknown media: %q", trailing)
	}
	// We are left with just the name or fiddle hash, dereference that.
	fiddleHash, err := n.DereferenceID(id)
	return fiddleHash, media, err
}
