// 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 }

// The set method 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
}

// 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.
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
}
