// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package file

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

// Path is a clean absolute path with platform specific separators.
type Path struct{ value string }

// Abs is the primary constructor of new Path objects from strings using either the / or system separator.
func Abs(path string) Path {
	abs, err := filepath.Abs(filepath.FromSlash(path))
	if err != nil {
		return Path{path}
	}
	return Path{filepath.Clean(abs)}
}

// ExecutablePath returns the path to the running executable.
func ExecutablePath() Path {
	path := Abs(os.Args[0])
	if path.Exists() {
		return path
	}
	path, err := FindExecutable(os.Args[0])
	if err != nil {
		panic(err)
	}
	return path
}

// FindExecutable searches the system search path for the named binary, and returns a non empty Path if found.
func FindExecutable(name string) (Path, error) {
	path, err := exec.LookPath(name)
	return Abs(path), err
}

// IsEmpty returns true if the path has no value
func (p Path) IsEmpty() bool { return p.value == "" }

// System returns the full absolute path using the system separator.
func (p Path) System() string { return p.value }

// Slash returns the full absolute path using the / separator.
func (p Path) Slash() string { return filepath.ToSlash(p.value) }

// The default string form uses the system representation.
func (p Path) String() string { return p.value }

// Set assigns the value of the path.
// This conforms to the flag variable interface.
func (p *Path) Set(value string) error {
	*p = Abs(value)
	return nil
}

// Parent returns the parent directory of the path, if it has one.
// It will return the canonical version of the path if it is a root.
func (p Path) Parent() Path { return Path{filepath.Dir(p.value)} }

// Basename returns the name part of the path (without directories).
func (p Path) Basename() string { return filepath.Base(p.value) }

// Ext returns the extension of the path, including the '.', or an empty string
// if the path has no extension.
func (p Path) Ext() string { return filepath.Ext(p.value) }

// Split returns the parent and name of the path.
func (p Path) Split() (Path, string) {
	dir, name := filepath.Split(p.value)
	return Path{dir}, name
}

// SplitExt returns the path excluding the file extension and the file
// extension. The extension includes the '.'.
func (p Path) SplitExt() (Path, string) {
	ext := p.Ext()
	return Path{p.value[:len(p.value)-len(ext)]}, ext
}

// Join returns a path formed from joining this base with a child path.
// If there are any / characters in the strings, they will be converted to they system separator.
func (p Path) Join(join ...string) Path {
	if len(join) == 0 {
		return p
	}
	trailing := filepath.Join(join...)
	trailing = filepath.FromSlash(trailing)
	return Path{filepath.Clean(filepath.Join(p.value, trailing))}
}

// Files reads the list of files in path.
func (p Path) Files() PathList {
	infos, _ := ioutil.ReadDir(p.value)
	list := PathList{}
	for _, i := range infos {
		if !i.IsDir() {
			list = append(list, Path{filepath.Join(p.value, i.Name())})
		}
	}
	return list
}

// Glob adds each pattern to the path in turn, and uses filepath.Glob to resolve that pattern to a list of files.
func (p Path) Glob(pattern ...string) PathList {
	list := PathList{}
	for _, test := range pattern {
		matches, err := filepath.Glob(filepath.Join(p.value, test))
		if err != nil {
			return PathList{}
		}
		for _, match := range matches {
			list = append(list, Path{match})
		}
	}
	return list
}

// Info returns the file information for ths path.
func (p Path) Info() os.FileInfo {
	info, _ := os.Stat(p.value)
	return info
}

// Exists returns true if this File exists.
func (p Path) Exists() bool {
	return p.Info() != nil
}

// Timestamp returns the last modified time reported by the file system.
func (p Path) Timestamp() time.Time {
	info := p.Info()
	if info == nil || info.IsDir() {
		return time.Time{}
	}
	return info.ModTime()
}

// Contains returns true if this directory contains the other.
func (p Path) Contains(other Path) bool {
	if len(p.value) >= len(other.value) {
		return false
	}
	return strings.HasPrefix(other.value, p.value)
}

// RelativeTo returns the path of this File relative to base.
func (p Path) RelativeTo(base Path) (string, error) {
	return filepath.Rel(base.value, p.value)
}

// ChangeExt returns a new Path with the extension changed to ext.
// ext should being with a '.' to change extension, or be an empty string to
// remove the extension.
func (p Path) ChangeExt(ext string) Path {
	prev := filepath.Ext(p.value)
	return Path{p.value[:len(p.value)-len(prev)] + ext}
}

// Matches returns true if the Path matches any of the patterns.
func (p Path) Matches(patterns ...string) bool {
	for _, pattern := range patterns {
		matched, _ := filepath.Match(pattern, p.Basename())
		if matched {
			return true
		}
	}
	return false
}
