// Copyright (C) 2015 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 build

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"

	"android.googlesource.com/platform/tools/gpu/maker"
)

// File represents the path to a file or directory.
type File string

// Path returns a File formed from the joined path segments.
func Path(segments ...string) File {
	return File(filepath.Join(segments...))
}

// Join returns a File formed from joining this File with ext.
func (f File) Join(ext ...string) File {
	return File(filepath.Join(append([]string{string(f)}, ext...)...))
}

// RelativeTo returns the path of this File relative to base.
func (f File) RelativeTo(base File) string {
	rel, err := filepath.Rel(string(base), string(f))
	if err != nil {
		panic(err)
	}
	return rel
}

// Absolute returns the absolute path of this File.
func (f File) Absolute() string {
	abs, err := filepath.Abs(string(f))
	if err != nil {
		panic(fmt.Errorf("filepath.Abs(%s) returned error: %v", f, err))
	}
	return abs
}

// Exists returns true if this File exists.
func (f File) Exists() bool {
	_, err := os.Stat(string(f.Absolute()))
	return err == nil
}

// Contains returns true if this directory contains the file f.
func (d File) Contains(f File) bool {
	a := d.Absolute()
	b := f.Absolute()
	if len(b) <= len(a)+1 {
		return false
	}
	return b[:len(a)] == a && b[len(a)] == filepath.Separator
}

// Name returns the name part of the File (without directories).
func (f File) Name() string {
	return filepath.Base(string(f))
}

// Dir returns the directory part of the File (without filename).
func (f File) Dir() string {
	return filepath.Dir(string(f))
}

// Ext returns the extension of the file, including the '.', or an empty string
// if the file has no extension.
func (f File) Ext() string {
	return filepath.Ext(string(f))
}

// ChangeExt returns a new File with the extension changed to ext.
func (f File) ChangeExt(ext string) File {
	prev := filepath.Ext(string(f))
	noext := f[:len(f)-len(prev)]
	return noext + File(ext)
}

// Glob returns a FileSet of all files matching any of the specified patterns.
func (f File) Glob(patterns ...string) FileSet {
	fs := FileSet{}
	for _, patten := range patterns {
		glob, err := filepath.Glob(string(f.Join(patten)))
		if err != nil {
			panic(err)
		}
		files := make(FileSet, len(glob))
		for i := range glob {
			files[i] = File(glob[i])
		}
		fs = fs.Append(files...)
	}
	return fs
}

// Matches returns true if the File matches any of the patterns.
func (f File) Matches(patterns ...string) bool {
	abs := filepath.Base(f.Absolute())
	for _, pattern := range patterns {
		matched, err := filepath.Match(pattern, abs)
		if err != nil {
			panic(err)
		}
		if matched {
			return true
		}
	}
	return false
}

// MkdirAll creates the directory hierarchy to hold this File.
func (f File) MkdirAll() {
	abs := f.Absolute()
	dir, _ := filepath.Split(abs)
	if len(dir) > 0 {
		if err := os.MkdirAll(dir, os.ModePerm); err != nil {
			panic(err)
		}
	}
}

// CopyTo copied this File to dst, replacing any existing file at dst.
func (f File) CopyTo(dst File) error {
	s, err := os.Open(f.Absolute())
	if err != nil {
		return fmt.Errorf("Open copy source failed: %v", err)
	}
	defer s.Close()

	fi, err := s.Stat()
	if err != nil {
		return fmt.Errorf("Stat copy source failed: %v", err)
	}

	d, err := os.OpenFile(dst.Absolute(), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, fi.Mode())
	if err != nil {
		return fmt.Errorf("Create copy target failed: %v", err)
	}
	defer d.Close()

	if _, err = io.Copy(d, s); err != nil {
		return fmt.Errorf("Copy file data failed: %v", err)
	}
	return nil
}

// Exec executes this File with the specified arguments.
func (f File) Exec(env Environment, args ...string) error {
	path, err := f.LookPath()
	if err != nil {
		return err
	}
	return f.ExecAt(env, File(path.Dir()), args...)
}

// ExecAt executes this File with the specified arguments with the working
// directory set to wd.
func (f File) ExecAt(env Environment, wd File, args ...string) error {
	if !wd.Exists() {
		return fmt.Errorf("The working directory '%s' does not exist", wd)
	}
	path, err := f.LookPath()
	if err != nil {
		return err
	}
	verbose := 0
	if env.Verbose {
		verbose = 1
	}
	return maker.ExecAt(wd.Absolute(), verbose, path.Absolute(), args...)
}

// LookPath returns the path to f, searching the system PATHs.
func (f File) LookPath() (File, error) {
	if f.Exists() {
		return f, nil
	} else {
		path, err := exec.LookPath(string(f))
		return File(path), err
	}
}
