package analyze

import (
	"io/ioutil"
	"path/filepath"
	"regexp"
	"strings"
	"sync"

	"github.com/bazelbuild/rules_typescript/ts_auto_deps/workspace"
)

// ts_auto_depsImport represents a single import in a TypeScript source.
type ts_auto_depsImport struct {
	// importPath can be an ES6 path ('./foo/bar'), but also a namespace ('goog:...').
	// This is the import path as it appears in the TypeScript source.
	importPath string
	// knownTarget is the (fully qualified) bazel target providing importPath.
	// It's either found by locateMissingTargets or taken from a ts_auto_deps comment.
	knownTarget string
	location    sourceLocation
}

// resolvedPath is the path to the import relative to the root of the
// workspace. For example, an import of './foo' in the 'bar/baz' directory
// would have a path from root of 'bar/baz/foo'.
//
// Absolute imports have no resolvedPath since the physical location of
// these imports depends on the dependencies of the target the source
// location is a member of. For example, an import of 'foo/bar' would have
// no resolvedPath.
func (i *ts_auto_depsImport) resolvedPath() string {
	if strings.HasPrefix(i.importPath, "./") || strings.HasPrefix(i.importPath, "../") {
		// If the import is relative to the source location, use the source
		// location to form a "canonical" path from the root.
		return filepath.Clean(filepath.Join(filepath.Dir(i.location.sourcePath), i.importPath))
	} else if trim := strings.TrimPrefix(i.importPath, workspace.Name()+"/"); trim != i.importPath {
		return trim
	}
	// The import is an absolute import and therefore does not have a definite
	// resolved path.
	return i.importPath
}

// sourceLocation points to a position in a source file.
type sourceLocation struct {
	// Workspace root relative source path.
	sourcePath string
	// offset and length are byte offsets, line is the 1-indexed source line (considering only \n as breaks).
	offset, length, line int
}

// extractAllImports extracts the TypeScript imports from paths.
//
// paths should be relative to root. The root will be joined to each path
// to construct a physical path to each file.
func extractAllImports(root string, paths []string) (map[string][]*ts_auto_depsImport, []error) {
	allImports := make(map[string][]*ts_auto_depsImport)
	var (
		errors []error
		mutex  sync.Mutex
		group  sync.WaitGroup
	)
	for _, path := range paths {
		group.Add(1)
		go func(path string) {
			defer group.Done()
			imports, err := extractImports(root, path)
			// Lock the mutex to prevent concurrent writes.
			mutex.Lock()
			defer mutex.Unlock()
			if err != nil {
				errors = append(errors, err)
				return
			}
			allImports[path] = imports
		}(path)
	}
	group.Wait()
	return allImports, errors
}

// extractImports extracts the TypeScript imports from a single file. path
// should be a path from the root to the file.
func extractImports(root, path string) ([]*ts_auto_depsImport, error) {
	d, err := ioutil.ReadFile(filepath.Join(root, path))
	if err != nil {
		return nil, err
	}
	return parseImports(path, d), nil
}

const (
	ts_auto_depsFrom  = `^[ \t]*//[ \t]+ts_auto_deps:[^\n]*?from[ \t]+(?P<Target>//\S+)$`
	importPreface     = `^[ \t]*(?:import|export)\b\s*`
	wildcardTerm      = `\*(?:\s*as\s+\S+)?` // "as..." is optional to match exports.
	identifiersClause = `(?:\{[^}]*\}|\S+|` + wildcardTerm + `)`
	symbolsTerm       = `(?:` + identifiersClause + `(?:,\s*` + identifiersClause + `)?\s*\bfrom\b\s*)?`
	url               = `['"](?P<URL>[^'";]+)['"]\s*;?`
	namespaceComment  = `(?:\s*//[ \t]*from[ \t]+(?P<Target>//\S+)$)?`
)

var importRE = regexp.MustCompile("(?ms)" +
	"(?:" + ts_auto_depsFrom + ")|" +
	"(?:" + importPreface + symbolsTerm + url + namespaceComment + ")")

// parseImports scans contents for imports (ES6 modules, ts_auto_deps comments), and
// returns a list of ts_auto_depsImports. knownTarget is already filled in for imports
// that have ts_auto_deps comments.
func parseImports(sourcePath string, contents []byte) []*ts_auto_depsImport {
	var imports []*ts_auto_depsImport
	lastOffset := 0
	line := 1
	column := 1
	for _, matchIndices := range importRE.FindAllSubmatchIndex(contents, -1) {
		imp := &ts_auto_depsImport{}
		imports = append(imports, imp)
		// matchIndices[0, 1]: full RE match
		imp.location.sourcePath = sourcePath
		for lastOffset < matchIndices[1] {
			// Iterate to the *end* of the import statement.
			// The ts_auto_deps comment must be placed at the end of the "import" statement.
			// This offset has to be exactly the end of the import for ts_auto_deps later on
			// to insert the '// from' comment in the correct line.
			column++
			if contents[lastOffset] == '\n' {
				line++
				column = 1
			}
			lastOffset++
		}
		imp.location.offset = matchIndices[0]
		imp.location.length = matchIndices[1] - matchIndices[0]
		imp.location.line = line
		if matchIndices[2] >= 0 {
			// matchIndices[2, 3]: Target for a // ts_auto_deps: ... from ... comment.
			imp.knownTarget = string(contents[matchIndices[2]:matchIndices[3]])
		} else {
			// matchIndices[4, 5]: URL in import x from 'url';
			imp.importPath = string(contents[matchIndices[4]:matchIndices[5]])
		}
		if matchIndices[6] >= 0 {
			// matchIndices[6, 7]: Target for a // from comment
			imp.knownTarget = string(contents[matchIndices[6]:matchIndices[7]])
		}
	}
	return imports
}
