// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package project

import (
	"fmt"

	"go.fuchsia.dev/jiri"
	"go.fuchsia.dev/jiri/gitutil"
	"go.fuchsia.dev/jiri/tool"
)

type ReferenceState struct {
	Name     string
	Revision string
}

type BranchState struct {
	*ReferenceState
	Tracking *ReferenceState
}

type ProjectState struct {
	Branches       []BranchState
	CurrentBranch  BranchState
	HasUncommitted bool
	HasUntracked   bool
	Project        Project
}

func setProjectState(jirix *jiri.X, state *ProjectState, checkDirty bool, ch chan<- error) {
	var err error
	scm := gitutil.New(jirix, gitutil.RootDirOpt(state.Project.Path))
	branches, err := scm.GetAllBranchesInfo()
	if err != nil {
		ch <- err
		return
	}
	state.CurrentBranch = BranchState{
		&ReferenceState{
			Name: "",
		},
		nil,
	}
	for _, branch := range branches {
		b := BranchState{
			&ReferenceState{
				Name:     branch.Name,
				Revision: branch.Revision,
			},
			nil,
		}
		if branch.Tracking != nil {
			b.Tracking = &ReferenceState{
				Name:     branch.Tracking.Name,
				Revision: branch.Tracking.Revision,
			}
		}
		state.Branches = append(state.Branches, b)
		if branch.IsHead {
			state.CurrentBranch = b
		}
	}
	if state.CurrentBranch.Name == "" {
		if state.CurrentBranch.Revision, err = scm.CurrentRevision(); err != nil {
			ch <- err
			return
		}
	}
	if checkDirty {
		state.HasUncommitted, err = scm.HasUncommittedChanges()
		if err != nil {
			ch <- fmt.Errorf("Cannot get uncommited changes for project %q: %v", state.Project.Name, err)
			return
		}
		state.HasUntracked, err = scm.HasUntrackedFiles()
		if err != nil {
			ch <- fmt.Errorf("Cannot get untracked changes for project %q: %v", state.Project.Name, err)
			return
		}
	}
	ch <- nil
}

func GetProjectStates(jirix *jiri.X, projects Projects, checkDirty bool) (map[ProjectKey]*ProjectState, error) {
	jirix.TimerPush("Get project states")
	defer jirix.TimerPop()
	states := make(map[ProjectKey]*ProjectState, len(projects))
	sem := make(chan error, len(projects))
	for key, project := range projects {
		state := &ProjectState{
			Project: project,
		}
		states[key] = state
		// jirix is not threadsafe, so we make a clone for each goroutine.
		go setProjectState(jirix.Clone(tool.ContextOpts{}), state, checkDirty, sem)
	}
	for range projects {
		err := <-sem
		if err != nil {
			return nil, err
		}
	}
	return states, nil
}

func GetProjectState(jirix *jiri.X, project Project, checkDirty bool) (*ProjectState, error) {
	sem := make(chan error, 1)
	state := &ProjectState{
		Project: project,
	}
	setProjectState(jirix, state, checkDirty, sem)
	return state, <-sem
}
