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.CommitURL, 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
}
