// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package populate

import (
	"fmt"

	"github.com/google/slothfs/gitiles"
	"github.com/google/slothfs/manifest"

	git "github.com/libgit2/git2go"
)

// FetchManifest gets the default manifest file from a Gitiles server.
func FetchManifest(service *gitiles.Service, repo, branch string) (*manifest.Manifest, error) {
	project := service.NewRepoService(repo)

	// When checking this out, it's called "manifest.xml". Go figure.
	c, err := project.GetBlob(branch, "default.xml")
	if err != nil {
		return nil, err
	}
	mf, err := manifest.Parse(c)
	if err != nil {
		return nil, err
	}

	return mf, nil
}

// DerefManifest uses the Gitiles JSON interface to fill in
// Project.Revision and Project.CloneURL in the given manifest.
func DerefManifest(service *gitiles.Service, mf *manifest.Manifest) error {
	// Collect all branch names we might care about, so we can
	// request data from all branches in one JSON call.  Normally,
	// all projects use the same branch, but individual projects
	// may specify a special branch.
	branchSet := map[string]struct{}{}

	var todoProjects []int
	for i, p := range mf.Project {
		rev := mf.ProjectRevision(&p)

		// According to the repo doc, the revision should be a branch,
		// either like 'refs/heads/master' or 'master'. We abuse this field by
		// also allowing commit SHA1s.
		if _, err := git.NewOid(rev); err == nil {
			// Already a SHA1, don't change.
			continue
		}

		branchSet[rev] = struct{}{}
		todoProjects = append(todoProjects, i)
	}

	var branches []string
	for k := range branchSet {
		branches = append(branches, k)
	}

	repos, err := service.List(branches)
	if err != nil {
		return err
	}
	for _, i := range todoProjects {
		p := &mf.Project[i]

		proj, ok := repos[p.Name]
		if !ok {
			return fmt.Errorf("server list doesn't mention repo %s", p.Name)
		}

		p.CloneURL = proj.CloneURL

		branch := mf.ProjectRevision(p)
		commit, ok := proj.Branches[branch]
		if !ok {
			return fmt.Errorf("branch %q for repo %s not returned", branch, p.Name)
		}

		p.Revision = commit
	}
	return nil
}
