package cfg

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"sort"
	"strconv"
	"strings"

	"github.com/Masterminds/glide/mirrors"
	"github.com/Masterminds/vcs"
	"github.com/sdboyer/gps"
	"gopkg.in/yaml.v2"
)

// Config is the top-level configuration object.
type Config struct {

	// Name is the name of the package or application.
	Name string `yaml:"package"`

	// Description is a short description for a package, application, or library.
	// This description is similar but different to a Go package description as
	// it is for marketing and presentation purposes rather than technical ones.
	Description string `json:"description,omitempty"`

	// Home is a url to a website for the package.
	Home string `yaml:"homepage,omitempty"`

	// License provides either a SPDX license or a path to a file containing
	// the license. For more information on SPDX see http://spdx.org/licenses/.
	// When more than one license an SPDX expression can be used.
	License string `yaml:"license,omitempty"`

	// Owners is an array of owners for a project. See the Owner type for
	// more detail. These can be one or more people, companies, or other
	// organizations.
	Owners Owners `yaml:"owners,omitempty"`

	// Ignore contains a list of packages to ignore fetching. This is useful
	// when walking the package tree (including packages of packages) to list
	// those to skip.
	Ignore []string `yaml:"ignore,omitempty"`

	// Imports contains a list of all dependency constraints for a project. For
	// more detail on how these are captured see the Dependency type.
	// TODO rename
	// TODO mapify
	Imports Dependencies `yaml:"dependencies"`

	// DevImports contains the test or other development dependency constraints
	// for a project. See the Dependency type for more details on how this is
	// recorded.
	// TODO rename
	// TODO mapify
	DevImports Dependencies `yaml:"testDependencies"`
}

// A transitive representation of a dependency for importing and exporting to yaml.
type cf struct {
	Name        string       `yaml:"package"`
	Description string       `yaml:"description,omitempty"`
	Home        string       `yaml:"homepage,omitempty"`
	License     string       `yaml:"license,omitempty"`
	Owners      Owners       `yaml:"owners,omitempty"`
	Ignore      []string     `yaml:"ignore,omitempty"`
	Imports     Dependencies `yaml:"dependencies,omitempty"`
	DevImports  Dependencies `yaml:"testDependencies,omitempty"`
	// these fields guarantee that this struct fails to unmarshal legacy yamls
	Compat  int `yaml:"import,omitempty"`
	Compat2 int `yaml:"testImport,omitempty"`
}

// ConfigFromYaml returns an instance of Config from YAML
func ConfigFromYaml(yml []byte) (cfg *Config, legacy bool, err error) {
	cfg = &Config{}
	err = yaml.Unmarshal(yml, cfg)
	if err != nil {
		lcfg := &lConfig1{}
		err = yaml.Unmarshal(yml, &lcfg)
		if err == nil {
			legacy = true
			cfg, err = lcfg.Convert()
		}
	}

	return
}

// Marshal converts a Config instance to YAML
func (c *Config) Marshal() ([]byte, error) {
	yml, err := yaml.Marshal(&c)
	if err != nil {
		return []byte{}, err
	}
	return yml, nil
}

// UnmarshalYAML is a hook for gopkg.in/yaml.v2 in the unmarshalling process
func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
	newConfig := &cf{}
	if err := unmarshal(&newConfig); err != nil {
		return err
	}
	c.Name = newConfig.Name
	c.Description = newConfig.Description
	c.Home = newConfig.Home
	c.License = newConfig.License
	c.Owners = newConfig.Owners
	c.Ignore = newConfig.Ignore
	c.Imports = newConfig.Imports
	c.DevImports = newConfig.DevImports

	// Cleanup the Config object now that we have it.
	err := c.DeDupe()

	return err
}

// MarshalYAML is a hook for gopkg.in/yaml.v2 in the marshaling process
func (c *Config) MarshalYAML() (interface{}, error) {
	newConfig := &cf{
		Name:        c.Name,
		Description: c.Description,
		Home:        c.Home,
		License:     c.License,
		Owners:      c.Owners,
		Ignore:      c.Ignore,
	}
	i, err := c.Imports.Clone().DeDupe()
	if err != nil {
		return newConfig, err
	}

	di, err := c.DevImports.Clone().DeDupe()
	if err != nil {
		return newConfig, err
	}

	newConfig.Imports = i
	newConfig.DevImports = di

	return newConfig, nil
}

// HasDependency returns true if the given name is listed as an import or dev import.
func (c *Config) HasDependency(name string) bool {
	for _, d := range c.Imports {
		if d.Name == name {
			return true
		}
	}
	for _, d := range c.DevImports {
		if d.Name == name {
			return true
		}
	}
	return false
}

// DependencyConstraints lists all the non-test dependency constraints
// described in a glide manifest in a way gps will understand.
func (c *Config) DependencyConstraints() []gps.ProjectConstraint {
	return gpsifyDeps(c.Imports)
}

// TestDependencyConstraints lists all the test dependency constraints described
// in a glide manifest in a way gps will understand.
func (c *Config) TestDependencyConstraints() []gps.ProjectConstraint {
	return gpsifyDeps(c.DevImports)
}

func gpsifyDeps(deps Dependencies) []gps.ProjectConstraint {
	cp := make([]gps.ProjectConstraint, len(deps))
	for k, d := range deps {
		cp[k] = gps.ProjectConstraint{
			Ident: gps.ProjectIdentifier{
				ProjectRoot: gps.ProjectRoot(d.Name),
				NetworkName: d.Repository,
			},
			Constraint: d.GetConstraint(),
		}
	}

	return cp
}

func (c *Config) IgnorePackages() map[string]bool {
	m := make(map[string]bool)
	for _, ig := range c.Ignore {
		m[ig] = true
	}
	return m
}

func (c *Config) Overrides() gps.ProjectConstraints {
	return nil
}

// HasIgnore returns true if the given name is listed on the ignore list.
func (c *Config) HasIgnore(name string) bool {
	for _, v := range c.Ignore {

		// Check for both a name and to make sure sub-packages are ignored as
		// well.
		if v == name || strings.HasPrefix(name, v+"/") {
			return true
		}
	}

	return false
}

// Clone performs a deep clone of the Config instance
func (c *Config) Clone() *Config {
	n := &Config{}
	n.Name = c.Name
	n.Description = c.Description
	n.Home = c.Home
	n.License = c.License
	n.Owners = c.Owners.Clone()
	n.Ignore = c.Ignore
	n.Imports = c.Imports.Clone()
	n.DevImports = c.DevImports.Clone()
	return n
}

// WriteFile writes a Glide YAML file.
//
// This is a convenience function that marshals the YAML and then writes it to
// the given file. If the file exists, it will be clobbered.
func (c *Config) WriteFile(glidepath string) error {
	o, err := c.Marshal()
	if err != nil {
		return err
	}
	return ioutil.WriteFile(glidepath, o, 0666)
}

// DeDupe consolidates duplicate dependencies on a Config instance
func (c *Config) DeDupe() error {

	// Remove duplicates in the imports
	var err error
	c.Imports, err = c.Imports.DeDupe()
	if err != nil {
		return err
	}
	c.DevImports, err = c.DevImports.DeDupe()
	if err != nil {
		return err
	}

	// If the name on the config object is part of the imports remove it.
	found := -1
	for i, dep := range c.Imports {
		if dep.Name == c.Name {
			found = i
		}
	}
	if found >= 0 {
		c.Imports = append(c.Imports[:found], c.Imports[found+1:]...)
	}

	found = -1
	for i, dep := range c.DevImports {
		if dep.Name == c.Name {
			found = i
		}
	}
	if found >= 0 {
		c.DevImports = append(c.DevImports[:found], c.DevImports[found+1:]...)
	}

	// If something is on the ignore list remove it from the imports.
	for _, v := range c.Ignore {
		found = -1
		for k, d := range c.Imports {
			if v == d.Name {
				found = k
			}
		}
		if found >= 0 {
			c.Imports = append(c.Imports[:found], c.Imports[found+1:]...)
		}

		found = -1
		for k, d := range c.DevImports {
			if v == d.Name {
				found = k
			}
		}
		if found >= 0 {
			c.DevImports = append(c.DevImports[:found], c.DevImports[found+1:]...)
		}
	}

	return nil
}

// AddImport appends dependencies to the import list, deduplicating as we go.
func (c *Config) AddImport(deps ...*Dependency) error {
	t := c.Imports
	t = append(t, deps...)
	t, err := t.DeDupe()
	if err != nil {
		return err
	}
	c.Imports = t
	return nil
}

// Hash generates a sha256 hash for a given Config
func (c *Config) Hash() (string, error) {
	yml, err := c.Marshal()
	if err != nil {
		return "", err
	}

	hash := sha256.New()
	hash.Write(yml)
	return fmt.Sprintf("%x", hash.Sum(nil)), nil
}

// Dependencies is a collection of Dependency
type Dependencies []*Dependency

// Get a dependency by name
func (d Dependencies) Get(name string) *Dependency {
	for _, dep := range d {
		if dep.Name == name {
			return dep
		}
	}
	return nil
}

// Has checks if a dependency is on a list of dependencies such as import or testImport
func (d Dependencies) Has(name string) bool {
	for _, dep := range d {
		if dep.Name == name {
			return true
		}
	}
	return false
}

// Remove removes a dependency from a list of dependencies
func (d Dependencies) Remove(name string) Dependencies {
	found := -1
	for i, dep := range d {
		if dep.Name == name {
			found = i
		}
	}

	if found >= 0 {
		copy(d[found:], d[found+1:])
		d[len(d)-1] = nil
		return d[:len(d)-1]
	}
	return d
}

// Clone performs a deep clone of Dependencies
func (d Dependencies) Clone() Dependencies {
	n := make(Dependencies, 0, len(d))
	for _, v := range d {
		n = append(n, v.Clone())
	}
	return n
}

// DeDupe cleans up duplicates on a list of dependencies.
func (d Dependencies) DeDupe() (Dependencies, error) {
	checked := map[string]int{}
	imports := make(Dependencies, 0, 1)
	i := 0
	for _, dep := range d {
		// The first time we encounter a dependency add it to the list
		if val, ok := checked[dep.Name]; !ok {
			checked[dep.Name] = i
			imports = append(imports, dep)
			i++
		} else {
			// In here we've encountered a dependency for the second time.
			// Make sure the details are the same or return an error.
			v := imports[val]
			// Have to do string-based comparison
			if dep.ConstraintsEq(*v) {
				return d, fmt.Errorf("Import %s repeated with different versions '%s' and '%s'", dep.Name, dep.GetConstraint(), v.GetConstraint())
			}
			if dep.Repository != v.Repository {
				return d, fmt.Errorf("Import %s repeated with different Repository details", dep.Name)
			}
		}
	}

	return imports, nil
}

// Dependency describes a package that the present package depends upon.
type Dependency struct {
	Name       string
	VcsType    string // TODO remove
	Repository string
	Branch     string
	Version    string
}

// A transitive representation of a dependency for yaml import/export.
type dep struct {
	Name       string `yaml:"package"`
	Version    string `yaml:"version,omitempty"`
	Branch     string `yaml:"branch,omitempty"`
	Repository string `yaml:"repo,omitempty"`
}

// DependencyFromLock converts a Lock to a Dependency
func DependencyFromLock(lock *Lock) *Dependency {
	d := &Dependency{
		Name:       lock.Name,
		Repository: lock.Repository,
	}

	// Because it's not allowed to have both, if we see both, prefer version
	// over branch
	if lock.Version != "" {
		d.Version = lock.Version
	} else if lock.Branch != "" {
		d.Branch = lock.Branch
	} else {
		d.Version = lock.Revision
	}

	return d
}

// GetConstraint constructs an appropriate gps.Constraint from the Dependency's
// string input data.
func (d Dependency) GetConstraint() gps.Constraint {
	// If neither or both Version and Branch are set, accept anything
	if d.IsUnconstrained() {
		return gps.Any()
	} else if d.Version != "" {
		return DeduceConstraint(d.Version)
	} else {
		// only case left is a non-empty branch
		return gps.NewBranch(d.Branch)
	}
}

// IsUnconstrained indicates if this dependency has no constraint information,
// version or branch.
func (d Dependency) IsUnconstrained() bool {
	return (d.Version != "" && d.Branch != "") || (d.Version == "" && d.Branch == "")
}

// ConstraintsEq checks if the constraints on two Dependency are exactly equal.
func (d Dependency) ConstraintsEq(d2 Dependency) bool {
	// Having both branch and version set is always an error, so if either have
	// it, then return false
	if (d.Version != "" && d.Branch != "") || (d2.Version != "" && d2.Branch != "") {
		return false
	}
	// Neither being set, though, is OK
	if (d.Version == "" && d.Branch == "") || (d2.Version == "" && d2.Branch == "") {
		return true
	}

	// Now, xors
	if d.Version != "" && d.Version == d2.Version {
		return true
	}
	if d.Branch == d2.Branch {
		return true
	}
	return false
}

// UnmarshalYAML is a hook for gopkg.in/yaml.v2 in the unmarshaling process
func (d *Dependency) UnmarshalYAML(unmarshal func(interface{}) error) error {
	newDep := dep{}
	err := unmarshal(&newDep)
	if err != nil {
		return err
	}

	if newDep.Version != "" && newDep.Branch != "" {
		return fmt.Errorf("Cannot set both a both a branch and a version constraint for %q", d.Name)
	}

	d.Name = newDep.Name
	d.Repository = newDep.Repository
	d.Version = newDep.Version
	d.Branch = newDep.Branch

	return nil
}

// DeduceConstraint tries to puzzle out what kind of version is given in a string -
// semver, a revision, or as a fallback, a plain tag
func DeduceConstraint(s string) gps.Constraint {
	// always semver if we can
	c, err := gps.NewSemverConstraint(s)
	if err == nil {
		return c
	}

	slen := len(s)
	if slen == 40 {
		if _, err = hex.DecodeString(s); err == nil {
			// Whether or not it's intended to be a SHA1 digest, this is a
			// valid byte sequence for that, so go with Revision. This
			// covers git and hg
			return gps.Revision(s)
		}
	}
	// Next, try for bzr, which has a three-component GUID separated by
	// dashes. There should be two, but the email part could contain
	// internal dashes
	if strings.Count(s, "-") >= 2 {
		// Work from the back to avoid potential confusion from the email
		i3 := strings.LastIndex(s, "-")
		// Skip if - is last char, otherwise this would panic on bounds err
		if slen == i3+1 {
			return gps.NewVersion(s)
		}

		if _, err = hex.DecodeString(s[i3+1:]); err == nil {
			i2 := strings.LastIndex(s[:i3], "-")
			if _, err = strconv.ParseUint(s[i2+1:i3], 10, 64); err == nil {
				// Getting this far means it'd pretty much be nuts if it's not a
				// bzr rev, so don't bother parsing the email.
				return gps.Revision(s)
			}
		}
	}

	// If not a plain SHA1 or bzr custom GUID, assume a plain version.
	//
	// svn, you ask? lol, madame. lol.
	return gps.NewVersion(s)
}

// MarshalYAML is a hook for gopkg.in/yaml.v2 in the marshaling process
func (d *Dependency) MarshalYAML() (interface{}, error) {
	newDep := &dep{
		Name:       d.Name,
		Repository: d.Repository,
		Version:    d.Version,
		Branch:     d.Branch,
	}

	return newDep, nil
}

// Remote returns the remote location to fetch source from. This location is
// the central place where mirrors can alter the location.
func (d *Dependency) Remote() string {
	var r string

	if d.Repository != "" {
		r = d.Repository
	} else {
		r = "https://" + d.Name
	}

	f, nr, _ := mirrors.Get(r)
	if f {
		return nr
	}

	return r
}

// Vcs returns the VCS type to fetch source from.
func (d *Dependency) Vcs() string {
	var r string

	if d.Repository != "" {
		r = d.Repository
	} else {
		r = "https://" + d.Name
	}

	f, _, nv := mirrors.Get(r)
	if f {
		return nv
	}

	return d.VcsType
}

// GetRepo retrieves a Masterminds/vcs repo object configured for the root
// of the package being retrieved.
// TODO remove
func (d *Dependency) GetRepo(dest string) (vcs.Repo, error) {
	// The remote location is either the configured repo or the package
	// name as an https url.
	remote := d.Remote()

	VcsType := d.Vcs()

	// If the VCS type has a value we try that first.
	if len(VcsType) > 0 && VcsType != "None" {
		switch vcs.Type(VcsType) {
		case vcs.Git:
			return vcs.NewGitRepo(remote, dest)
		case vcs.Svn:
			return vcs.NewSvnRepo(remote, dest)
		case vcs.Hg:
			return vcs.NewHgRepo(remote, dest)
		case vcs.Bzr:
			return vcs.NewBzrRepo(remote, dest)
		default:
			return nil, fmt.Errorf("Unknown VCS type %s set for %s", VcsType, d.Name)
		}
	}

	// When no type set we try to autodetect.
	return vcs.NewRepo(remote, dest)
}

// Clone creates a clone of a Dependency
func (d *Dependency) Clone() *Dependency {
	var d2 Dependency
	d2 = *d
	return &d2
}

// Owners is a list of owners for a project.
type Owners []*Owner

// Clone performs a deep clone of Owners
func (o Owners) Clone() Owners {
	n := make(Owners, 0, 1)
	for _, v := range o {
		n = append(n, v.Clone())
	}
	return n
}

// Owner describes an owner of a package. This can be a person, company, or
// other organization. This is useful if someone needs to contact the
// owner of a package to address things like a security issue.
type Owner struct {

	// Name describes the name of an organization.
	Name string `yaml:"name,omitempty"`

	// Email is an email address to reach the owner at.
	Email string `yaml:"email,omitempty"`

	// Home is a url to a website for the owner.
	Home string `yaml:"homepage,omitempty"`
}

// Clone creates a clone of a Dependency
func (o *Owner) Clone() *Owner {
	return &Owner{
		Name:  o.Name,
		Email: o.Email,
		Home:  o.Home,
	}
}

func stringArrayDeDupe(s []string, items ...string) []string {
	for _, item := range items {
		exists := false
		for _, v := range s {
			if v == item {
				exists = true
			}
		}
		if !exists {
			s = append(s, item)
		}
	}
	sort.Strings(s)
	return s
}

func filterVcsType(vcs string) string {
	switch vcs {
	case "git", "hg", "bzr", "svn":
		return vcs
	case "mercurial":
		return "hg"
	case "bazaar":
		return "bzr"
	case "subversion":
		return "svn"
	default:
		return ""
	}
}

func normalizeSlash(k string) string {
	return strings.Replace(k, "\\", "/", -1)
}
