package child

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"regexp"
	"strconv"

	"go.skia.org/infra/autoroll/go/config"
	"go.skia.org/infra/autoroll/go/config_vars"
	"go.skia.org/infra/autoroll/go/revision"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
)

// parseSemanticVersion returns the set of integer versions which make up the
// given semantic version, as specified by the capture groups in the given
// Regexp.
func parseSemanticVersion(regex *regexp.Regexp, ver string) ([]int, error) {
	matches := regex.FindStringSubmatch(ver)
	if len(matches) > 1 {
		matchInts := make([]int, len(matches)-1)
		for idx, a := range matches[1:] {
			i, err := strconv.Atoi(a)
			if err != nil {
				return matchInts, fmt.Errorf("Failed to parse int from regex match string; is the regex incorrect?")
			}
			matchInts[idx] = i
		}
		return matchInts, nil
	}
	return nil, errInvalidGCSVersion
}

// compareSemanticVersions returns 1 if A comes before B, -1 if A comes
// after B, and 0 if they are equal.
func compareSemanticVersions(a, b []int) int {
	for i := 0; ; i++ {
		if i == len(a) && i == len(b) {
			return 0
		} else if i == len(a) {
			return 1
		} else if i == len(b) {
			return -1
		}
		if a[i] < b[i] {
			return 1
		} else if a[i] > b[i] {
			return -1
		}
	}
}

// semVersion is an implementation of gcsVersion which uses semantic versioning.
type semVersion struct {
	id      string
	version []int
}

// See documentation for gcsVersion interface.
func (v *semVersion) Compare(other gcsVersion) int {
	a := v.version
	b := other.(*semVersion).version
	return compareSemanticVersions(a, b)
}

// See documentation for gcsVersion interface.
func (v *semVersion) Id() string {
	return v.id
}

// See documentation for getGCSVersionFunc.
func getSemanticGCSVersion(regex *regexp.Regexp, rev *revision.Revision) (gcsVersion, error) {
	ver, err := parseSemanticVersion(regex, rev.Id)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return &semVersion{
		id:      rev.Id,
		version: ver,
	}, nil
}

// ErrShortRevNoMatch is returned by ShortRev when the revision ID does not
// match the regular expression.
var ErrShortRevNoMatch = errors.New("Revision ID does not match provided regular expression")

// ShortRev shortens the revision ID using the given regular expression.
func ShortRev(reTmpl string, id string) (string, error) {
	shortRevRegex, err := regexp.Compile(reTmpl)
	if err != nil {
		return "", skerr.Wrapf(err, "Failed to compile ShortRevRegex")
	}
	matches := shortRevRegex.FindStringSubmatch(id)
	if len(matches) == 0 {
		// TODO(borenet): It'd be nice to log an error here to
		// indicate that the regex might be incorrect, but this
		// function may be called for revisions which are not
		// valid and thus may not match the regex. That would
		// cause an unhelpful error spew in the log.
		return "", ErrShortRevNoMatch
	} else if len(matches) == 1 {
		return matches[0], nil
	} else {
		// This indicates that there is at least one sub-match. We don't
		// have any way of combining multiple sub-matches into one short
		// revision, so just use the first one.
		return matches[1], nil
	}
}

// semVerShortRev shortens the revision ID using the given regular expression.
func semVerShortRev(reTmpl string, id string) string {
	shortRev, err := ShortRev(reTmpl, id)
	if err != nil {
		if err == ErrShortRevNoMatch {
			// TODO(borenet): It'd be nice to log an error here to
			// indicate that the regex might be incorrect, but this
			// function may be called for revisions which are not
			// valid and thus may not match the regex. That would
			// cause an unhelpful error spew in the log.
		} else {
			sklog.Error(err)
		}
		return id
	}
	return shortRev
}

// NewSemVerGCS returns a Child which uses semantic versioning to compare object
// versions in GCS.
func NewSemVerGCS(ctx context.Context, c *config.SemVerGCSChildConfig, reg *config_vars.Registry, client *http.Client) (*gcsChild, error) {
	if err := c.Validate(); err != nil {
		return nil, skerr.Wrap(err)
	}
	versionRegex, err := config_vars.NewTemplate(c.VersionRegex)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	if err := reg.Register(versionRegex); err != nil {
		return nil, skerr.Wrap(err)
	}
	var shortRevRegex *config_vars.Template
	if c.ShortRevRegex != "" {
		shortRevRegex, err = config_vars.NewTemplate(c.ShortRevRegex)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		if err := reg.Register(shortRevRegex); err != nil {
			return nil, skerr.Wrap(err)
		}
	}
	getGCSVersion := func(rev *revision.Revision) (gcsVersion, error) {
		versionRegex, err := regexp.Compile(versionRegex.String())
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		return getSemanticGCSVersion(versionRegex, rev)
	}
	shortRevFn := func(id string) string {
		if shortRevRegex != nil {
			return semVerShortRev(shortRevRegex.String(), id)
		}
		return id
	}
	return newGCS(ctx, c.Gcs, client, getGCSVersion, shortRevFn)
}
