package dependency

import (
	"bytes"
	"io"
	"os"
	"path/filepath"
	"strings"
	"text/scanner"

	"github.com/Masterminds/glide/msg"
	"github.com/Masterminds/glide/util"
)

var osList []string
var archList []string

func init() {
	// The supported systems are listed in
	// https://github.com/golang/go/blob/master/src/go/build/syslist.go
	// The lists are not exported so we need to duplicate them here.
	osListString := "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
	osList = strings.Split(osListString, " ")

	archListString := "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc s390 s390x sparc sparc64"
	archList = strings.Split(archListString, " ")
}

// IterativeScan attempts to obtain a list of imported dependencies from a
// package. This scanning is different from ImportDir as part of the go/build
// package. It looks over different permutations of the supported OS/Arch to
// try and find all imports. This is different from setting UseAllFiles to
// true on the build Context. It scopes down to just the supported OS/Arch.
//
// Note, there are cases where multiple packages are in the same directory. This
// usually happens with an example that has a main package and a +build tag
// of ignore. This is a bit of a hack. It causes UseAllFiles to have errors.
func IterativeScan(path string) ([]string, error) {

	// TODO(mattfarina): Add support for release tags.

	tgs, _ := readBuildTags(path)
	// Handle the case of scanning with no tags
	tgs = append(tgs, "")

	var pkgs []string
	for _, tt := range tgs {

		// split the tag combination to look at permutations.
		ts := strings.Split(tt, ",")
		var ttgs []string
		var arch string
		var ops string
		for _, ttt := range ts {
			dirty := false
			if strings.HasPrefix(ttt, "!") {
				dirty = true
				ttt = strings.TrimPrefix(ttt, "!")
			}
			if isSupportedOs(ttt) {
				if dirty {
					ops = getOsValue(ttt)
				} else {
					ops = ttt
				}
			} else if isSupportedArch(ttt) {
				if dirty {
					arch = getArchValue(ttt)
				} else {
					arch = ttt
				}
			} else {
				if !dirty {
					ttgs = append(ttgs, ttt)
				}
			}
		}

		// Handle the case where there are no tags but we need to iterate
		// on something.
		if len(ttgs) == 0 {
			ttgs = append(ttgs, "")
		}

		b, err := util.GetBuildContext()
		if err != nil {
			return []string{}, err
		}

		// Make sure use all files is off
		b.UseAllFiles = false

		// Set the OS and Arch for this pass
		b.GOARCH = arch
		b.GOOS = ops
		b.BuildTags = ttgs
		msg.Debug("Scanning with Arch(%s), OS(%s), and Build Tags(%v)", arch, ops, ttgs)

		pk, err := b.ImportDir(path, 0)
		if err != nil && strings.HasPrefix(err.Error(), "no buildable Go source files in") {
			continue
		} else if err != nil {
			msg.Debug("Problem parsing package at %s for %s %s", path, ops, arch)
			return []string{}, err
		}

		for _, dep := range pk.Imports {
			found := false
			for _, p := range pkgs {
				if p == dep {
					found = true
				}
			}
			if !found {
				pkgs = append(pkgs, dep)
			}
		}
	}

	return pkgs, nil
}

func readBuildTags(p string) ([]string, error) {
	_, err := os.Stat(p)
	if err != nil {
		return []string{}, err
	}

	d, err := os.Open(p)
	if err != nil {
		return []string{}, err
	}

	objects, err := d.Readdir(-1)
	if err != nil {
		return []string{}, err
	}

	var tags []string
	for _, obj := range objects {

		// only process Go files
		if strings.HasSuffix(obj.Name(), ".go") {
			fp := filepath.Join(p, obj.Name())

			co, err := readGoContents(fp)
			if err != nil {
				return []string{}, err
			}

			// Only look at places where we had a code comment.
			if len(co) > 0 {
				t := findTags(co)
				for _, tg := range t {
					found := false
					for _, tt := range tags {
						if tt == tg {
							found = true
						}
					}
					if !found {
						tags = append(tags, tg)
					}
				}
			}
		}
	}

	return tags, nil
}

// Read contents of a Go file up to the package declaration. This can be used
// to find the the build tags.
func readGoContents(fp string) ([]byte, error) {
	f, err := os.Open(fp)
	defer f.Close()
	if err != nil {
		return []byte{}, err
	}

	var s scanner.Scanner
	s.Init(f)
	var tok rune
	var pos scanner.Position
	for tok != scanner.EOF {
		tok = s.Scan()

		// Getting the token text will skip comments by default.
		tt := s.TokenText()
		// build tags will not be after the package declaration.
		if tt == "package" {
			pos = s.Position
			break
		}
	}

	buf := bytes.NewBufferString("")
	f.Seek(0, 0)
	_, err = io.CopyN(buf, f, int64(pos.Offset))
	if err != nil {
		return []byte{}, err
	}

	return buf.Bytes(), nil
}

// From a byte slice of a Go file find the tags.
func findTags(co []byte) []string {
	p := co
	var tgs []string
	for len(p) > 0 {
		line := p
		if i := bytes.IndexByte(line, '\n'); i >= 0 {
			line, p = line[:i], p[i+1:]
		} else {
			p = p[len(p):]
		}
		line = bytes.TrimSpace(line)
		// Only look at comment lines that are well formed in the Go style
		if bytes.HasPrefix(line, []byte("//")) {
			line = bytes.TrimSpace(line[len([]byte("//")):])
			if len(line) > 0 && line[0] == '+' {
				f := strings.Fields(string(line))

				// We've found a +build tag line.
				if f[0] == "+build" {
					for _, tg := range f[1:] {
						tgs = append(tgs, tg)
					}
				}
			}
		}
	}

	return tgs
}

// Get an OS value that's not the one passed in.
func getOsValue(n string) string {
	for _, o := range osList {
		if o != n {
			return o
		}
	}

	return n
}

func isSupportedOs(n string) bool {
	for _, o := range osList {
		if o == n {
			return true
		}
	}

	return false
}

// Get an Arch value that's not the one passed in.
func getArchValue(n string) string {
	for _, o := range archList {
		if o != n {
			return o
		}
	}

	return n
}

func isSupportedArch(n string) bool {
	for _, o := range archList {
		if o == n {
			return true
		}
	}

	return false
}
