/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 project

import (
	"fmt"
	"os"
	"path"
	"path/filepath"
	"strings"

	log "github.com/Sirupsen/logrus"

	"mynewt.apache.org/newt/newt/compat"
	"mynewt.apache.org/newt/newt/deprepo"
	"mynewt.apache.org/newt/newt/downloader"
	"mynewt.apache.org/newt/newt/install"
	"mynewt.apache.org/newt/newt/interfaces"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/newt/pkg"
	"mynewt.apache.org/newt/newt/repo"
	"mynewt.apache.org/newt/newt/ycfg"
	"mynewt.apache.org/newt/util"
)

var globalProject *Project = nil

const PROJECT_FILE_NAME = "project.yml"

var ignoreSearchDirs []string = []string{
	"bin",
	"repos",
}

type Project struct {
	// Name of this project
	name string

	// Base path of the project
	BasePath string

	packages interfaces.PackageList

	// Contains all the repos that form this project.  Each repo is in one of
	// two states:
	//    * description: Only the repo's basic description fields have been
	//                   read from `project.yml` or from a dependent repo's
	//                   `repository.yml` file.  This repo's `repository.yml`
	//                   file still needs to be read.
	//    * complete: The repo's `repository.yml` file exists and has been
	//                read.
	repos deprepo.RepoMap

	// The local repository at the top-level of the project.  This repo is
	// excluded from most repo operations.
	localRepo *repo.Repo

	// Required versions of installed repos, as read from `project.yml`.
	rootRepoReqs deprepo.RequirementMap

	warnings []string

	// Indicates the repos whose version we couldn't detect.  Prevents
	// duplicate warnings.
	unknownRepoVers map[string]struct{}

	yc ycfg.YCfg
}

func initProject(dir string) error {
	var err error

	globalProject, err = LoadProject(dir)
	if err != nil {
		return err
	}
	if err := globalProject.loadPackageList(); err != nil {
		return err
	}

	return nil
}

func initialize() error {
	if globalProject == nil {
		wd, err := os.Getwd()
		wd = filepath.ToSlash(wd)
		if err != nil {
			return util.NewNewtError(err.Error())
		}
		if err := initProject(wd); err != nil {
			return err
		}
	}
	return nil
}

func TryGetProject() (*Project, error) {
	if err := initialize(); err != nil {
		return nil, err
	}
	return globalProject, nil
}

func GetProject() *Project {
	if _, err := TryGetProject(); err != nil {
		panic(err.Error())
	}

	return globalProject
}

func ResetProject() {
	globalProject = nil
}

func ResetDeps(newList interfaces.PackageList) interfaces.PackageList {
	return nil
	if globalProject == nil {
		return nil
	}
	oldList := globalProject.packages
	globalProject.packages = newList

	if newList == nil {
		globalProject.loadPackageList()
	}
	return oldList
}

func NewProject(dir string) (*Project, error) {
	proj := &Project{}

	if err := proj.Init(dir); err != nil {
		return nil, err
	}

	return proj, nil
}

func (proj *Project) Path() string {
	return proj.BasePath
}

func (proj *Project) Name() string {
	return proj.name
}

func (proj *Project) Repos() map[string]*repo.Repo {
	return proj.repos
}

func (proj *Project) FindRepo(rname string) *repo.Repo {
	if rname == repo.REPO_NAME_LOCAL {
		return proj.LocalRepo()
	} else {
		r, _ := proj.repos[rname]
		return r
	}
}

func (proj *Project) FindRepoPath(rname string) string {
	r := proj.FindRepo(rname)
	if r == nil {
		return ""
	}

	return r.Path()
}

func (proj *Project) GetRepoVersion(
	rname string) (*newtutil.RepoVersion, error) {

	// First, try to read the repo's `version.yml` file.
	r := proj.repos[rname]
	if r == nil {
		return nil, nil
	}

	ver, err := r.InstalledVersion()
	if err != nil {
		return nil, err
	}

	if ver == nil {
		commit, err := r.CurrentHash()
		if err != nil {
			return nil, err
		}
		if proj.unknownRepoVers == nil {
			proj.unknownRepoVers = map[string]struct{}{}
		}

		if _, ok := proj.unknownRepoVers[rname]; !ok {
			proj.unknownRepoVers[rname] = struct{}{}

			util.StatusMessage(util.VERBOSITY_QUIET,
				"WARNING: Could not detect version of installed repo \"%s\"; "+
					"assuming 0.0.0/%s\n", r.Name(), commit)
		}
		ver = &newtutil.RepoVersion{
			Commit: commit,
		}
	}

	return ver, nil
}

// XXX: Incorrect comment.
// Indicates whether the specified repo is present in the `project.state` file.
func (proj *Project) RepoIsInstalled(rname string) bool {
	ver, err := proj.GetRepoVersion(rname)
	return err == nil && ver != nil
}

func (proj *Project) RepoIsRoot(rname string) bool {
	return proj.rootRepoReqs[rname] != nil
}

func (proj *Project) LocalRepo() *repo.Repo {
	return proj.localRepo
}

func (proj *Project) Warnings() []string {
	return proj.warnings
}

// Selects repositories from the global state that satisfy the specified
// predicate.
func (proj *Project) SelectRepos(pred func(r *repo.Repo) bool) []*repo.Repo {
	all := proj.repos.Sorted()
	var filtered []*repo.Repo

	for _, r := range all {
		if pred(r) {
			filtered = append(filtered, r)
		}
	}

	return filtered
}

// Installs or upgrades repos matching the specified predicate.
func (proj *Project) InstallIf(
	upgrade bool, force bool, ask bool,
	predicate func(r *repo.Repo) bool) error {

	// Make sure we have an up to date copy of all `repository.yml` files.
	if err := proj.downloadRepositoryYmlFiles(); err != nil {
		return err
	}

	// Now that all repos have been successfully fetched, we can finish the
	// install procedure locally.

	// Determine which repos the user wants to install or upgrade.
	specifiedRepoList := proj.SelectRepos(predicate)

	inst, err := install.NewInstaller(proj.repos, proj.rootRepoReqs)
	if err != nil {
		return err
	}

	if upgrade {
		return inst.Upgrade(specifiedRepoList, force, ask)
	} else {
		return inst.Install(specifiedRepoList, force, ask)
	}
}

// Syncs (i.e., applies `git pull` to) repos matching the specified predicate.
func (proj *Project) SyncIf(
	force bool, ask bool, predicate func(r *repo.Repo) bool) error {

	// Make sure we have an up to date copy of all `repository.yml` files.
	if err := proj.downloadRepositoryYmlFiles(); err != nil {
		return err
	}

	// Determine which repos the user wants to sync.
	repoList := proj.SelectRepos(predicate)

	inst, err := install.NewInstaller(proj.repos, proj.rootRepoReqs)
	if err != nil {
		return err
	}

	return inst.Sync(repoList, force, ask)
}

func (proj *Project) InfoIf(predicate func(r *repo.Repo) bool,
	remote bool) error {

	if remote {
		// Make sure we have an up to date copy of all `repository.yml` files.
		if err := proj.downloadRepositoryYmlFiles(); err != nil {
			return err
		}
	}

	// Determine which repos the user wants info about.
	repoList := proj.SelectRepos(predicate)

	// Ignore errors.  We will deal with bad repos individually when we display
	// info about them.
	inst, _ := install.NewInstaller(proj.repos, proj.rootRepoReqs)
	if err := inst.Info(repoList, remote); err != nil {
		return err
	}

	return nil
}

// Loads a complete repo definition from the appropriate `repository.yml` file.
// The supplied fields form a basic repo description as read from `project.yml`
// or from another repo's dependency list.
//
// @param name                  The name of the repo to read.
// @param fields                Fields containing the basic repo description.
//
// @return *Repo                The fully-read repo on success; nil on failure.
// @return error                Error on failure.
func (proj *Project) loadRepo(name string, fields map[string]string) (
	*repo.Repo, error) {

	// First, read the repo description from the supplied fields.
	if fields["type"] == "" {
		return nil,
			util.FmtNewtError("Missing type for repository %s", name)
	}

	dl, err := downloader.LoadDownloader(name, fields)
	if err != nil {
		return nil, err
	}

	// Construct a new repo object from the basic description information.
	r, err := repo.NewRepo(name, dl)
	if err != nil {
		return nil, err
	}

	for _, ignDir := range ignoreSearchDirs {
		r.AddIgnoreDir(ignDir)
	}

	// Read the full repo definition from its `repository.yml` file.
	if err := r.Read(); err != nil {
		return r, err
	}

	// Warn the user about incompatibilities with this version of newt.
	ver, err := proj.GetRepoVersion(name)
	if err != nil {
		return nil, err
	}
	if ver != nil {
		code, msg := r.CheckNewtCompatibility(*ver, newtutil.NewtVersion)
		switch code {
		case compat.NEWT_COMPAT_GOOD:
		case compat.NEWT_COMPAT_WARN:
			util.StatusMessage(util.VERBOSITY_QUIET, "WARNING: %s.\n", msg)
		case compat.NEWT_COMPAT_ERROR:
			return nil, util.NewNewtError(msg)
		}
	}

	// XXX: This log message assumes a "github" type repo.
	log.Debugf("Loaded repository %s (type: %s, user: %s, repo: %s)", name,
		fields["type"], fields["user"], fields["repo"])

	return r, nil
}

func (proj *Project) checkNewtVer() error {
	compatSms := proj.yc.GetValStringMapString(
		"project.newt_compatibility", nil)

	// If this project doesn't have a newt compatibility map, just assume there
	// is no incompatibility.
	if len(compatSms) == 0 {
		return nil
	}

	tbl, err := compat.ParseNcTable(compatSms)
	if err != nil {
		return util.FmtNewtError("Error reading project.yml: %s", err.Error())
	}

	code, msg := tbl.CheckNewtVer(newtutil.NewtVersion)
	msg = fmt.Sprintf("This version of newt (%s) is incompatible with "+
		"your project; %s", newtutil.NewtVersion.String(), msg)

	switch code {
	case compat.NEWT_COMPAT_GOOD:
		return nil
	case compat.NEWT_COMPAT_WARN:
		util.StatusMessage(util.VERBOSITY_QUIET, "WARNING: %s.\n", msg)
		return nil
	case compat.NEWT_COMPAT_ERROR:
		return util.NewNewtError(msg)
	default:
		return nil
	}
}

// Loads the `repository.yml` file for each depended-on repo.  This
func (proj *Project) loadRepoDeps(download bool) error {
	seen := map[string]struct{}{}

	loadDeps := func(r *repo.Repo) ([]*repo.Repo, error) {
		var newRepos []*repo.Repo

		depMap := r.CommitDepMap()
		for _, depSlice := range depMap {
			for _, dep := range depSlice {
				if _, ok := seen[dep.Name]; !ok {
					seen[r.Name()] = struct{}{}

					depRepo := proj.repos[dep.Name]
					if depRepo == nil {
						depRepo, _ = proj.loadRepo(dep.Name, dep.Fields)
						proj.repos[dep.Name] = depRepo
					}
					newRepos = append(newRepos, depRepo)

					if download {
						if _, err := depRepo.UpdateDesc(); err != nil {
							return nil, err
						}
					}
				}
			}
		}

		return newRepos, nil
	}

	curRepos := proj.repos.Sorted()
	for len(curRepos) > 0 {
		var nextRepos []*repo.Repo

		for _, r := range curRepos {
			depRepos, err := loadDeps(r)
			if err != nil {
				return err
			}

			nextRepos = append(nextRepos, depRepos...)
		}

		curRepos = nextRepos
	}

	return nil
}

func (proj *Project) downloadRepositoryYmlFiles() error {
	// Download the `repository.yml` file for each root-level repo (those
	// specified in the `project.yml` file).
	for _, r := range proj.repos.Sorted() {
		if !r.IsLocal() {
			if _, err := r.UpdateDesc(); err != nil {
				return err
			}
		}
	}

	// Download the `repository.yml` file for each depended-on repo.
	if err := proj.loadRepoDeps(true); err != nil {
		return err
	}

	return nil
}

func (proj *Project) loadConfig() error {
	yc, err := newtutil.ReadConfig(proj.BasePath,
		strings.TrimSuffix(PROJECT_FILE_NAME, ".yml"))
	if err != nil {
		return util.NewNewtError(err.Error())
	}
	// Store configuration object for access to future values,
	// this avoids keeping every string around as a project variable when
	// we need to process it later.
	proj.yc = yc

	proj.name = yc.GetValString("project.name", nil)

	// Local repository always included in initialization
	r, err := repo.NewLocalRepo(proj.name)
	if err != nil {
		return err
	}

	proj.repos[proj.name] = r
	proj.localRepo = r
	for _, ignDir := range ignoreSearchDirs {
		r.AddIgnoreDir(ignDir)
	}

	// Assume every item starting with "repository." is a repository descriptor
	// and try to load it.
	for k, _ := range yc.AllSettings() {
		repoName := strings.TrimPrefix(k, "repository.")
		if repoName != k {
			fields := yc.GetValStringMapString(k, nil)
			r, _ := proj.loadRepo(repoName, fields)

			verReqs, err := newtutil.ParseRepoVersionReqs(fields["vers"])
			if err != nil {
				return util.FmtNewtError(
					"Repo \"%s\" contains invalid version requirement: %s (%s)",
					repoName, fields["vers"], err.Error())
			}

			proj.repos[repoName] = r
			proj.rootRepoReqs[repoName] = verReqs
		}
	}

	// Read `repository.yml` files belonging to dependee repos from disk.
	// These repos might not be specified in the `project.yml` file, but they
	// are still part of the project.
	if err := proj.loadRepoDeps(false); err != nil {
		return err
	}

	ignoreDirs := yc.GetValStringSlice("project.ignore_dirs", nil)
	for _, ignDir := range ignoreDirs {
		repoName, dirName, err := newtutil.ParsePackageString(ignDir)
		if err != nil {
			return err
		}
		if repoName == "" {
			r = proj.LocalRepo()
		} else {
			r = proj.FindRepo(repoName)
		}
		if r == nil {
			return util.NewNewtError(
				fmt.Sprintf("ignore_dirs: unknown repo %s", repoName))
		}
		r.AddIgnoreDir(dirName)
	}

	if err := proj.checkNewtVer(); err != nil {
		return err
	}

	return nil
}

func (proj *Project) Init(dir string) error {
	proj.BasePath = filepath.ToSlash(filepath.Clean(dir))

	// Only one project per system, when created, set it as the global project
	interfaces.SetProject(proj)

	proj.repos = map[string]*repo.Repo{}
	proj.rootRepoReqs = map[string][]newtutil.RepoVersionReq{}

	// Load Project configuration
	if err := proj.loadConfig(); err != nil {
		return err
	}

	return nil
}

func (proj *Project) ResolveDependency(dep interfaces.DependencyInterface) interfaces.PackageInterface {
	type NamePath struct {
		name string
		path string
	}

	for _, pkgList := range proj.packages {
		for _, pkg := range *pkgList {
			if dep.SatisfiesDependency(pkg) {
				return pkg
			}
		}
	}

	return nil
}

func (proj *Project) ResolvePackage(
	dfltRepo interfaces.RepoInterface, name string) (*pkg.LocalPackage, error) {
	// Trim trailing slash from name.  This is necessary when tab
	// completion is used to specify the name.
	name = strings.TrimSuffix(name, "/")

	repoName, pkgName, err := newtutil.ParsePackageString(name)
	if err != nil {
		return nil, util.FmtNewtError("invalid package name: %s (%s)", name,
			err.Error())
	}

	var repo interfaces.RepoInterface
	if repoName == "" {
		repo = dfltRepo
	} else if proj.repos[repoName] != nil {
		repo = proj.repos[repoName]
	} else {
		return nil, util.FmtNewtError("invalid package name: %s (unkwn repo %s)",
			name, repoName)
	}
	dep, err := pkg.NewDependency(repo, pkgName)
	if err != nil {
		return nil, util.FmtNewtError("invalid package name: %s (%s)", name,
			err.Error())
	}
	if dep == nil {
		return nil, util.NewNewtError("invalid package name: " + name)
	}
	pack := proj.ResolveDependency(dep)
	if pack == nil {
		return nil, util.NewNewtError("unknown package: " + name)
	}

	return pack.(*pkg.LocalPackage), nil
}

// Resolves a path with an optional repo prefix (e.g., "@apache-mynewt-core").
func (proj *Project) ResolvePath(
	basePath string, name string) (string, error) {

	repoName, subPath, err := newtutil.ParsePackageString(name)
	if err != nil {
		return "", util.FmtNewtError("invalid path: %s (%s)", name,
			err.Error())
	}

	if repoName == "" {
		return basePath + "/" + subPath, nil
	} else {
		repo := proj.repos[repoName]
		if repo == nil {
			return "", util.FmtNewtError("Unknown repository: %s", repoName)
		}

		return repo.Path() + "/" + subPath, nil
	}
}

func findProjectDir(dir string) (string, error) {
	for {
		projFile := path.Clean(dir) + "/" + PROJECT_FILE_NAME

		log.Debugf("Searching for project file %s", projFile)
		if util.NodeExist(projFile) {
			break
		}

		// Move back one directory and continue searching
		dir = path.Clean(dir + "../../")
		// path.Clean returns . if processing results in empty string.
		// Need to check for . on Windows.
		if dir == "/" || dir == "." {
			return "", util.NewNewtError("No project file found!")
		}
	}

	return dir, nil
}

func (proj *Project) loadPackageList() error {
	proj.packages = interfaces.PackageList{}

	// Go through a list of repositories, starting with local, and search for
	// packages / store them in the project package list.
	repos := proj.Repos()
	for name, repo := range repos {
		list, warnings, err := pkg.ReadLocalPackages(repo, repo.Path())
		if err == nil {
			proj.packages[name] = list
		}

		proj.warnings = append(proj.warnings, warnings...)
	}

	return nil
}

func (proj *Project) PackageList() interfaces.PackageList {
	return proj.packages
}

func (proj *Project) PackagesOfType(pkgType interfaces.PackageType) []interfaces.PackageInterface {
	matches := []interfaces.PackageInterface{}

	packs := proj.PackageList()
	for _, packHash := range packs {
		for _, pack := range *packHash {
			if pkgType == -1 || pack.Type() == pkgType {
				matches = append(matches, pack)
			}
		}
	}

	return matches
}

func LoadProject(dir string) (*Project, error) {
	projDir, err := findProjectDir(dir)
	if err != nil {
		return nil, err
	}

	proj, err := NewProject(projDir)

	return proj, err
}
