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