package protoparse

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

var errNoImportPathsForAbsoluteFilePath = errors.New("must specify at least one import path if any absolute file paths are given")

// ResolveFilenames tries to resolve fileNames into paths that are relative to
// directories in the given importPaths. The returned slice has the results in
// the same order as they are supplied in fileNames.
//
// The resulting names should be suitable for passing to Parser.ParseFiles.
//
// If no import paths are given and any file name is absolute, this returns an
// error.  If no import paths are given and all file names are relative, this
// returns the original file names. If a file name is already relative to one
// of the given import paths, it will be unchanged in the returned slice. If a
// file name given is relative to the current working directory, it will be made
// relative to one of the given import paths; but if it cannot be made relative
// (due to no matching import path), an error will be returned.
func ResolveFilenames(importPaths []string, fileNames ...string) ([]string, error) {
	if len(importPaths) == 0 {
		if containsAbsFilePath(fileNames) {
			// We have to do this as otherwise parseProtoFiles can result in duplicate symbols.
			// For example, assume we import "foo/bar/bar.proto" in a file "/home/alice/dev/foo/bar/baz.proto"
			// as we call ParseFiles("/home/alice/dev/foo/bar/bar.proto","/home/alice/dev/foo/bar/baz.proto")
			// with "/home/alice/dev" as our current directory. Due to the recursive nature of parseProtoFiles,
			// it will discover the import "foo/bar/bar.proto" in the input file, and call parse on this,
			// adding "foo/bar/bar.proto" to the parsed results, as well as "/home/alice/dev/foo/bar/bar.proto"
			// from the input file list. This will result in a
			// 'duplicate symbol SYMBOL: already defined as field in "/home/alice/dev/foo/bar/bar.proto'
			// error being returned from ParseFiles.
			return nil, errNoImportPathsForAbsoluteFilePath
		}
		return fileNames, nil
	}
	absImportPaths, err := absoluteFilePaths(importPaths)
	if err != nil {
		return nil, err
	}
	resolvedFileNames := make([]string, 0, len(fileNames))
	for _, fileName := range fileNames {
		resolvedFileName, err := resolveFilename(absImportPaths, fileName)
		if err != nil {
			return nil, err
		}
		resolvedFileNames = append(resolvedFileNames, resolvedFileName)
	}
	return resolvedFileNames, nil
}

func containsAbsFilePath(filePaths []string) bool {
	for _, filePath := range filePaths {
		if filepath.IsAbs(filePath) {
			return true
		}
	}
	return false
}

func absoluteFilePaths(filePaths []string) ([]string, error) {
	absFilePaths := make([]string, 0, len(filePaths))
	for _, filePath := range filePaths {
		absFilePath, err := canonicalize(filePath)
		if err != nil {
			return nil, err
		}
		absFilePaths = append(absFilePaths, absFilePath)
	}
	return absFilePaths, nil
}

func canonicalize(filePath string) (string, error) {
	absPath, err := filepath.Abs(filePath)
	if err != nil {
		return "", err
	}
	// this is kind of gross, but it lets us construct a resolved path even if some
	// path elements do not exist (a single call to filepath.EvalSymlinks would just
	// return an error, ENOENT, in that case).
	head := absPath
	tail := ""
	for {
		noLinks, err := filepath.EvalSymlinks(head)
		if err == nil {
			if tail != "" {
				return filepath.Join(noLinks, tail), nil
			}
			return noLinks, nil
		}

		if tail == "" {
			tail = filepath.Base(head)
		} else {
			tail = filepath.Join(filepath.Base(head), tail)
		}
		head = filepath.Dir(head)
		if head == "." {
			// ran out of path elements to try to resolve
			return absPath, nil
		}
	}
}

const dotPrefix = "." + string(filepath.Separator)
const dotDotPrefix = ".." + string(filepath.Separator)

func resolveFilename(absImportPaths []string, fileName string) (string, error) {
	if filepath.IsAbs(fileName) {
		return resolveAbsFilename(absImportPaths, fileName)
	}

	if !strings.HasPrefix(fileName, dotPrefix) && !strings.HasPrefix(fileName, dotDotPrefix) {
		// Use of . and .. are assumed to be relative to current working
		// directory. So if those aren't present, check to see if the file is
		// relative to an import path.
		for _, absImportPath := range absImportPaths {
			absFileName := filepath.Join(absImportPath, fileName)
			_, err := os.Stat(absFileName)
			if err != nil {
				continue
			}
			// found it! it was relative to this import path
			return fileName, nil
		}
	}

	// must be relative to current working dir
	return resolveAbsFilename(absImportPaths, fileName)
}

func resolveAbsFilename(absImportPaths []string, fileName string) (string, error) {
	absFileName, err := canonicalize(fileName)
	if err != nil {
		return "", err
	}
	for _, absImportPath := range absImportPaths {
		if isDescendant(absImportPath, absFileName) {
			resolvedPath, err := filepath.Rel(absImportPath, absFileName)
			if err != nil {
				return "", err
			}
			return resolvedPath, nil
		}
	}
	return "", fmt.Errorf("%s does not reside in any import path", fileName)
}

// isDescendant returns true if file is a descendant of dir. Both dir and file must
// be cleaned, absolute paths.
func isDescendant(dir, file string) bool {
	dir = filepath.Clean(dir)
	cur := file
	for {
		d := filepath.Dir(cur)
		if d == dir {
			return true
		}
		if d == "." || d == cur {
			// we've run out of path elements
			return false
		}
		cur = d
	}
}
