package action

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"

	"github.com/Masterminds/glide/cfg"
	"github.com/Masterminds/glide/dependency"
	"github.com/Masterminds/glide/msg"
	gpath "github.com/Masterminds/glide/path"
	"github.com/Masterminds/glide/repo"
	"github.com/sdboyer/gps"
)

// Install installs a vendor directory based on an existing Glide configuration.
func Install(installer *repo.Installer, io, so, sv bool) {
	base := "."
	// Ensure GOPATH
	EnsureGopath()
	EnsureVendorDir()
	conf := EnsureConfig()

	// TODO might need a better way for discovering the root
	vend, err := gpath.Vendor()
	if err != nil {
		msg.Die("Could not find the vendor dir: %s", err)
	}

	// Create the SourceManager for this run
	sm, err := gps.NewSourceManager(dependency.Analyzer{}, filepath.Join(installer.Home, "cache"))
	defer sm.Release()
	if err != nil {
		msg.Err(err.Error())
		return
	}

	rd := filepath.Dir(vend)
	rt, err := gps.ListPackages(rd, conf.Name)
	if err != nil {
		msg.Die("Error while scanning project: %s", err)
	}

	params := gps.SolveParameters{
		RootDir:         rd,
		RootPackageTree: rt,
		Manifest:        conf,
		Trace:           true,
		TraceLogger:     log.New(os.Stdout, "", 0),
	}

	var s gps.Solver
	if gpath.HasLock(base) {
		var legacy bool
		params.Lock, legacy, err = loadLockfile(base, conf)
		if legacy {
			msg.Warn("glide.lock was in a legacy format. An attempt will be made to automatically update it.")
		}
		if err != nil {
			msg.Err("Could not load lockfile.")
			return
		}

		s, err = gps.Prepare(params, sm)
		if err != nil {
			msg.Err("Could not set up solver: %s", err)
			return
		}
		digest := s.HashInputs()

		// Check if digests match, and warn if they don't
		if bytes.Equal(digest, params.Lock.InputHash()) {
			if so {
				msg.Err("glide.yaml is out of sync with glide.lock")
				return
			} else {
				msg.Warn("glide.yaml is out of sync with glide.lock!")
			}
		}

		gw := safeGroupWriter{
			resultLock:  params.Lock,
			vendor:      vend,
			sm:          sm,
			stripVendor: sv,
		}

		err = gw.writeAllSafe()
		if err != nil {
			msg.Err(err.Error())
			return
		}
	} else if io || so {
		msg.Err("No glide.lock file could be found.")
		return
	} else {
		// There is no lock, so we have to solve first
		s, err = gps.Prepare(params, sm)
		if err != nil {
			msg.Err("Could not set up solver: %s", err)
			return
		}

		r, err := s.Solve()
		if err != nil {
			// TODO better error handling
			msg.Err(err.Error())
			return
		}

		gw := safeGroupWriter{
			resultLock:  r,
			vendor:      vend,
			sm:          sm,
			stripVendor: sv,
		}

		err = gw.writeAllSafe()
		if err != nil {
			msg.Err(err.Error())
			return
		}
	}
}

// locksAreEquivalent compares the fingerprints between two locks to determine
// if they're equivalent.
//
// If the either of the locks are nil, the input hashes are different, the
// fingerprints are different, or any error is returned from fingerprinting,
// this function returns false.
func locksAreEquivalent(l1, l2 *cfg.Lockfile) bool {
	if l1 != nil && l2 != nil {
		if l1.Hash != l2.Hash {
			return false
		}

		f1, err := l1.Fingerprint()
		f2, err2 := l2.Fingerprint()
		if err == nil && err2 == nil && f1 == f2 {
			return true
		}
	}
	return false
}

// safeGroupWriter provides a slipshod-but-better-than-nothing approach to
// grouping together yaml, lock, and vendor dir writes.
type safeGroupWriter struct {
	conf              *cfg.Config
	lock              *cfg.Lockfile
	resultLock        gps.Lock
	sm                gps.SourceManager
	glidefile, vendor string
	stripVendor       bool
}

// writeAllSafe writes out some combination of config yaml, lock, and a vendor
// tree, to a temp dir, then moves them into place if and only if all the write
// operations succeeded. It also does its best to roll back if any moves fail.
//
// This helps to ensure glide doesn't exit with a partial write, resulting in an
// undefined disk state.
//
// - If a gw.conf is provided, it will be written to gw.glidefile
// - If gw.lock is provided without a gw.resultLock, it will be written to
//   `glide.lock` in the parent dir of gw.vendor
// - If gw.lock and gw.resultLock are both provided and are not equivalent,
//   the resultLock will be written to the same location as above, and a vendor
//   tree will be written to gw.vendor
// - If gw.resultLock is provided and gw.lock is not, it will write both a lock
//   and vendor dir in the same way
//
// Any of the conf, lock, or result can be omitted; the grouped write operation
// will continue for whichever inputs are present.
func (gw safeGroupWriter) writeAllSafe() error {
	// Decide which writes we need to do
	var writeConf, writeLock, writeVendor bool

	if gw.conf != nil {
		writeConf = true
	}

	if gw.resultLock != nil {
		if gw.lock == nil {
			writeLock, writeVendor = true, true
		} else {
			rlf, err := cfg.LockfileFromSolverLock(gw.resultLock)
			// This err really shouldn't occur, but could if we get an unpaired
			// version back from gps somehow
			if err != nil {
				return err
			}
			if !locksAreEquivalent(rlf, gw.lock) {
				writeLock, writeVendor = true, true
			}
		}
	} else if gw.lock != nil {
		writeLock = true
	}

	if !writeConf && !writeLock && !writeVendor {
		// nothing to do
		return nil
	}

	if writeConf && gw.glidefile == "" {
		return fmt.Errorf("Must provide a path if writing out a config yaml.")
	}

	if (writeLock || writeVendor) && gw.vendor == "" {
		return fmt.Errorf("Must provide a vendor dir if writing out a lock or vendor dir.")
	}

	if writeVendor && gw.sm == nil {
		return fmt.Errorf("Must provide a SourceManager if writing out a vendor dir.")
	}

	td, err := ioutil.TempDir(os.TempDir(), "glide")
	if err != nil {
		return fmt.Errorf("Error while creating temp dir for vendor directory: %s", err)
	}
	defer os.RemoveAll(td)

	if writeConf {
		if err := gw.conf.WriteFile(filepath.Join(td, "glide.yaml")); err != nil {
			return fmt.Errorf("Failed to write glide YAML file: %s", err)
		}
	}

	if writeLock {
		if gw.resultLock == nil {
			// the result lock is nil but the flag is on, so we must be writing
			// the other one
			if err := gw.lock.WriteFile(filepath.Join(td, gpath.LockFile)); err != nil {
				return fmt.Errorf("Failed to write glide lock file: %s", err)
			}
		} else {
			rlf, err := cfg.LockfileFromSolverLock(gw.resultLock)
			// As with above, this case really shouldn't get hit unless there's
			// a bug in gps, or guarantees change
			if err != nil {
				return err
			}
			if err := rlf.WriteFile(filepath.Join(td, gpath.LockFile)); err != nil {
				return fmt.Errorf("Failed to write glide lock file: %s", err)
			}
		}
	}

	if writeVendor {
		err = gps.WriteDepTree(filepath.Join(td, "vendor"), gw.resultLock, gw.sm, gw.stripVendor)
		if err != nil {
			return fmt.Errorf("Error while generating vendor tree: %s", err)
		}
	}

	// Move the existing files and dirs to the temp dir while we put the new
	// ones in, to provide insurance against errors for as long as possible
	var fail bool
	var failerr error
	type pathpair struct {
		from, to string
	}
	var restore []pathpair

	if writeConf {
		if _, err := os.Stat(gw.glidefile); err == nil {
			// move out the old one
			tmploc := filepath.Join(td, "glide.yaml-old")
			failerr = os.Rename(gw.glidefile, tmploc)
			if failerr != nil {
				fail = true
			} else {
				restore = append(restore, pathpair{from: tmploc, to: gw.glidefile})
			}
		}

		// move in the new one
		failerr = os.Rename(filepath.Join(td, "glide.yaml"), gw.glidefile)
		if failerr != nil {
			fail = true
		}
	}

	if !fail && writeLock {
		tgt := filepath.Join(filepath.Dir(gw.vendor), gpath.LockFile)
		if _, err := os.Stat(tgt); err == nil {
			// move out the old one
			tmploc := filepath.Join(td, "glide.lock-old")

			failerr = os.Rename(tgt, tmploc)
			if failerr != nil {
				fail = true
			} else {
				restore = append(restore, pathpair{from: tmploc, to: tgt})
			}
		}

		// move in the new one
		failerr = os.Rename(filepath.Join(td, gpath.LockFile), tgt)
		if failerr != nil {
			fail = true
		}
	}

	// have to declare out here so it's present later
	var vendorbak string
	if !fail && writeVendor {
		if _, err := os.Stat(gw.vendor); err == nil {
			// move out the old vendor dir. just do it into an adjacent dir, in
			// order to mitigate the possibility of a pointless cross-filesystem move
			vendorbak = gw.vendor + "-old"
			if _, err := os.Stat(vendorbak); err == nil {
				// Just in case that happens to exist...
				vendorbak = filepath.Join(td, "vendor-old")
			}
			failerr = os.Rename(gw.vendor, vendorbak)
			if failerr != nil {
				fail = true
			} else {
				restore = append(restore, pathpair{from: vendorbak, to: gw.vendor})
			}
		}

		// move in the new one
		failerr = os.Rename(filepath.Join(td, "vendor"), gw.vendor)
		if failerr != nil {
			fail = true
		}
	}

	// If we failed at any point, move all the things back into place, then bail
	if fail {
		for _, pair := range restore {
			// Nothing we can do on err here, we're already in recovery mode
			os.Rename(pair.from, pair.to)
		}
		return failerr
	}

	// Renames all went smoothly. The deferred os.RemoveAll will get the temp
	// dir, but if we wrote vendor, we have to clean that up directly

	if writeVendor {
		// Again, kinda nothing we can do about an error at this point
		os.RemoveAll(vendorbak)
	}

	return nil
}

// loadLockfile loads the contents of a glide.lock file.
func loadLockfile(base string, conf *cfg.Config) (*cfg.Lockfile, bool, error) {
	yml, err := ioutil.ReadFile(filepath.Join(base, gpath.LockFile))
	if err != nil {
		return nil, false, err
	}
	lock, legacy, err := cfg.LockfileFromYaml(yml)
	if err != nil {
		return nil, false, err
	}

	return lock, legacy, nil
}
