// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package os

import (
	"sync"
	"syscall"
	"time"
	"unsafe"
)

// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (file *File) Stat() (fi FileInfo, err error) {
	if file == nil || file.fd < 0 {
		return nil, syscall.EINVAL
	}
	if file.isdir() {
		// I don't know any better way to do that for directory
		return Stat(file.name)
	}
	if file.name == DevNull {
		return statDevNull()
	}
	var d syscall.ByHandleFileInformation
	e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
	if e != nil {
		return nil, &PathError{"GetFileInformationByHandle", file.name, e}
	}
	return &fileStat{
		name:    basename(file.name),
		size:    mkSize(d.FileSizeHigh, d.FileSizeLow),
		modTime: mkModTime(d.LastWriteTime),
		mode:    mkMode(d.FileAttributes),
		sys:     mkSysFromFI(&d),
	}, nil
}

// Stat returns a FileInfo structure describing the named file.
// If there is an error, it will be of type *PathError.
func Stat(name string) (fi FileInfo, err error) {
	if len(name) == 0 {
		return nil, &PathError{"Stat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
	}
	if name == DevNull {
		return statDevNull()
	}
	var d syscall.Win32FileAttributeData
	e := syscall.GetFileAttributesEx(syscall.StringToUTF16Ptr(name), syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&d)))
	if e != nil {
		return nil, &PathError{"GetFileAttributesEx", name, e}
	}
	path := name
	if !isAbs(path) {
		cwd, _ := Getwd()
		path = cwd + `\` + path
	}
	return &fileStat{
		name:    basename(name),
		size:    mkSize(d.FileSizeHigh, d.FileSizeLow),
		modTime: mkModTime(d.LastWriteTime),
		mode:    mkMode(d.FileAttributes),
		sys:     mkSys(path, d.LastAccessTime, d.CreationTime),
	}, nil
}

// Lstat returns the FileInfo structure describing the named file.
// If the file is a symbolic link, the returned FileInfo
// describes the symbolic link.  Lstat makes no attempt to follow the link.
// If there is an error, it will be of type *PathError.
func Lstat(name string) (fi FileInfo, err error) {
	// No links on Windows
	return Stat(name)
}

// statDevNull return FileInfo structure describing DevNull file ("NUL").
// It creates invented data, since none of windows api will return
// that information.
func statDevNull() (fi FileInfo, err error) {
	return &fileStat{
		name: DevNull,
		mode: ModeDevice | ModeCharDevice | 0666,
		sys: &winSys{
			// hopefully this will work for SameFile
			vol:   0,
			idxhi: 0,
			idxlo: 0,
		},
	}, nil
}

// basename removes trailing slashes and the leading
// directory name and drive letter from path name.
func basename(name string) string {
	// Remove drive letter
	if len(name) == 2 && name[1] == ':' {
		name = "."
	} else if len(name) > 2 && name[1] == ':' {
		name = name[2:]
	}
	i := len(name) - 1
	// Remove trailing slashes
	for ; i > 0 && (name[i] == '/' || name[i] == '\\'); i-- {
		name = name[:i]
	}
	// Remove leading directory name
	for i--; i >= 0; i-- {
		if name[i] == '/' || name[i] == '\\' {
			name = name[i+1:]
			break
		}
	}
	return name
}

func isSlash(c uint8) bool {
	return c == '\\' || c == '/'
}

func isAbs(path string) (b bool) {
	v := volumeName(path)
	if v == "" {
		return false
	}
	path = path[len(v):]
	if path == "" {
		return false
	}
	return isSlash(path[0])
}

func volumeName(path string) (v string) {
	if len(path) < 2 {
		return ""
	}
	// with drive letter
	c := path[0]
	if path[1] == ':' &&
		('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
			'A' <= c && c <= 'Z') {
		return path[:2]
	}
	// is it UNC
	if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
		!isSlash(path[2]) && path[2] != '.' {
		// first, leading `\\` and next shouldn't be `\`. its server name.
		for n := 3; n < l-1; n++ {
			// second, next '\' shouldn't be repeated.
			if isSlash(path[n]) {
				n++
				// third, following something characters. its share name.
				if !isSlash(path[n]) {
					if path[n] == '.' {
						break
					}
					for ; n < l; n++ {
						if isSlash(path[n]) {
							break
						}
					}
					return path[:n]
				}
				break
			}
		}
	}
	return ""
}

type winSys struct {
	sync.Mutex
	path              string
	atime, ctime      syscall.Filetime
	vol, idxhi, idxlo uint32
}

func mkSize(hi, lo uint32) int64 {
	return int64(hi)<<32 + int64(lo)
}

func mkModTime(mtime syscall.Filetime) time.Time {
	return time.Unix(0, mtime.Nanoseconds())
}

func mkMode(fa uint32) (m FileMode) {
	if fa&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
		m |= ModeDir
	}
	if fa&syscall.FILE_ATTRIBUTE_READONLY != 0 {
		m |= 0444
	} else {
		m |= 0666
	}
	return m
}

func mkSys(path string, atime, ctime syscall.Filetime) *winSys {
	return &winSys{
		path:  path,
		atime: atime,
		ctime: ctime,
	}
}

func mkSysFromFI(i *syscall.ByHandleFileInformation) *winSys {
	return &winSys{
		atime: i.LastAccessTime,
		ctime: i.CreationTime,
		vol:   i.VolumeSerialNumber,
		idxhi: i.FileIndexHigh,
		idxlo: i.FileIndexLow,
	}
}

func (s *winSys) loadFileId() error {
	if s.path == "" {
		// already done
		return nil
	}
	s.Lock()
	defer s.Unlock()
	h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(s.path), 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
	if e != nil {
		return e
	}
	defer syscall.CloseHandle(h)
	var i syscall.ByHandleFileInformation
	e = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
	if e != nil {
		return e
	}
	s.path = ""
	s.vol = i.VolumeSerialNumber
	s.idxhi = i.FileIndexHigh
	s.idxlo = i.FileIndexLow
	return nil
}

func sameFile(sys1, sys2 interface{}) bool {
	s1 := sys1.(*winSys)
	s2 := sys2.(*winSys)
	e := s1.loadFileId()
	if e != nil {
		panic(e)
	}
	e = s2.loadFileId()
	if e != nil {
		panic(e)
	}
	return s1.vol == s2.vol && s1.idxhi == s2.idxhi && s1.idxlo == s2.idxlo
}

// For testing.
func atime(fi FileInfo) time.Time {
	return time.Unix(0, fi.Sys().(*winSys).atime.Nanoseconds())
}
