package gitiles_common

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"net/http"

	"go.skia.org/infra/autoroll/go/config_vars"
	"go.skia.org/infra/autoroll/go/repo_manager/common/version_file_common"
	"go.skia.org/infra/autoroll/go/revision"
	"go.skia.org/infra/go/gitiles"
	"go.skia.org/infra/go/skerr"
)

// GitilesConfig provides configuration for GitilesRepo.
type GitilesConfig struct {
	// Branch is the name of the git branch to be tracked by the GitilesRepo.
	Branch *config_vars.Template `json:"branch"`
	// RepoURL is the git repository URL.
	RepoURL string `json:"repoURL"`
	// Dependencies is an optional specification of dependencies to track.
	// Revisions generated by the GitilesRepo will contain the pinned versions
	// of these dependencies.
	Dependencies []*version_file_common.VersionFileConfig `json:"dependencies,omitempty"`
}

// See documentation for util.Validator interface.
func (c *GitilesConfig) Validate() error {
	if c.Branch == nil {
		return errors.New("Branch is required.")
	}
	if err := c.Branch.Validate(); err != nil {
		return skerr.Wrap(err)
	}
	if c.RepoURL == "" {
		return errors.New("RepoURL is required.")
	}
	return nil
}

// GitilesRepo provides helpers for dealing with repos which use Gitiles.
type GitilesRepo struct {
	*gitiles.Repo
	branch *config_vars.Template
	deps   []*version_file_common.VersionFileConfig
}

// NewGitilesRepo returns a GitilesRepo instance.
func NewGitilesRepo(ctx context.Context, c GitilesConfig, reg *config_vars.Registry, client *http.Client) (*GitilesRepo, error) {
	if err := c.Validate(); err != nil {
		return nil, skerr.Wrap(err)
	}
	if err := reg.Register(c.Branch); err != nil {
		return nil, skerr.Wrap(err)
	}
	repo := gitiles.NewRepo(c.RepoURL, client)
	return &GitilesRepo{
		Repo:   repo,
		branch: c.Branch,
		deps:   c.Dependencies,
	}, nil
}

// Branch returns the resolved name of the branch tracked by this GitilesRepo.
func (r *GitilesRepo) Branch() string {
	return r.branch.String()
}

// GetRevision returns a revision.Revision instance associated with the given
// revision ID, which may be a commit hash or fully-qualified ref name.
func (r *GitilesRepo) GetRevision(ctx context.Context, id string) (*revision.Revision, error) {
	// Load the details for this revision.
	details, err := r.Details(ctx, id)
	if err != nil {
		return nil, skerr.Wrapf(err, "Failed to retrieve revision %q", id)
	}
	rev := revision.FromLongCommit(fmt.Sprintf(gitiles.COMMIT_URL, r.URL, "%s"), details)

	// Optionally load any dependencies.
	if len(r.deps) > 0 {
		deps, err := version_file_common.GetPinnedRevs(ctx, r.deps, func(ctx context.Context, path string) (string, error) {
			return r.GetFile(ctx, path, rev.Id)
		})
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		rev.Dependencies = deps
	}
	return rev, nil
}

// GetTipRevision returns a revision.Revision instance associated with the
// current tip of the branch tracked by this GitilesRepo.
func (r *GitilesRepo) GetTipRevision(ctx context.Context) (*revision.Revision, error) {
	return r.GetRevision(ctx, r.branch.String())
}

// LogFirstParent returns a slice of revision.Revision instances in the given range.
func (r *GitilesRepo) LogFirstParent(ctx context.Context, from, to *revision.Revision) ([]*revision.Revision, error) {
	commits, err := r.Repo.LogFirstParent(ctx, from.Id, to.Id)
	if err != nil {
		return nil, err
	}
	revs := make([]*revision.Revision, 0, len(commits))
	for _, commit := range commits {
		rev, err := r.GetRevision(ctx, commit.Hash)
		if err != nil {
			return nil, skerr.Wrapf(err, "Failed to retrieve revision")
		}
		revs = append(revs, rev)
	}
	return revs, nil
}

// GetFile retrieves the contents of the given file at the given ref.
func (r *GitilesRepo) GetFile(ctx context.Context, file, ref string) (string, error) {
	var buf bytes.Buffer
	if err := r.ReadFileAtRef(ctx, file, ref, &buf); err != nil {
		return "", skerr.Wrap(err)
	}
	return buf.String(), nil
}
