// 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 (
	"internal/syscall/windows"
	"syscall"
	"unsafe"
)

// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (file *File) Stat() (FileInfo, error) {
	if file == nil {
		return nil, ErrInvalid
	}

	if file.isdir() {
		// I don't know any better way to do that for directory
		return Stat(file.dirinfo.path)
	}
	if file.name == DevNull {
		return &devNullStat, nil
	}

	ft, err := file.pfd.GetFileType()
	if err != nil {
		return nil, &PathError{"GetFileType", file.name, err}
	}
	switch ft {
	case syscall.FILE_TYPE_PIPE, syscall.FILE_TYPE_CHAR:
		return &fileStat{name: basename(file.name), filetype: ft}, nil
	}

	var d syscall.ByHandleFileInformation
	err = file.pfd.GetFileInformationByHandle(&d)
	if err != nil {
		return nil, &PathError{"GetFileInformationByHandle", file.name, err}
	}
	return &fileStat{
		name: basename(file.name),
		sys: syscall.Win32FileAttributeData{
			FileAttributes: d.FileAttributes,
			CreationTime:   d.CreationTime,
			LastAccessTime: d.LastAccessTime,
			LastWriteTime:  d.LastWriteTime,
			FileSizeHigh:   d.FileSizeHigh,
			FileSizeLow:    d.FileSizeLow,
		},
		filetype: ft,
		vol:      d.VolumeSerialNumber,
		idxhi:    d.FileIndexHigh,
		idxlo:    d.FileIndexLow,
	}, nil
}

// statNolog implements Stat for Windows.
func statNolog(name string) (FileInfo, error) {
	if len(name) == 0 {
		return nil, &PathError{"Stat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
	}
	if name == DevNull {
		return &devNullStat, nil
	}
	namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
	if err != nil {
		return nil, &PathError{"Stat", name, err}
	}
	// Apparently (see https://golang.org/issues/19922#issuecomment-300031421)
	// GetFileAttributesEx is fastest approach to get file info.
	// It does not work for symlinks. But symlinks are rare,
	// so try GetFileAttributesEx first.
	var fs fileStat
	err = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fs.sys)))
	if err == nil && fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
		fs.path = name
		if !isAbs(fs.path) {
			fs.path, err = syscall.FullPath(fs.path)
			if err != nil {
				return nil, &PathError{"FullPath", name, err}
			}
		}
		fs.name = basename(name)
		return &fs, nil
	}
	// Use Windows I/O manager to dereference the symbolic link, as per
	// https://blogs.msdn.microsoft.com/oldnewthing/20100212-00/?p=14963/
	h, err := syscall.CreateFile(namep, 0, 0, nil,
		syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
	if err != nil {
		if err == windows.ERROR_SHARING_VIOLATION {
			// try FindFirstFile now that CreateFile failed
			return statWithFindFirstFile(name, namep)
		}
		return nil, &PathError{"CreateFile", name, err}
	}
	defer syscall.CloseHandle(h)

	var d syscall.ByHandleFileInformation
	err = syscall.GetFileInformationByHandle(h, &d)
	if err != nil {
		return nil, &PathError{"GetFileInformationByHandle", name, err}
	}
	return &fileStat{
		name: basename(name),
		sys: syscall.Win32FileAttributeData{
			FileAttributes: d.FileAttributes,
			CreationTime:   d.CreationTime,
			LastAccessTime: d.LastAccessTime,
			LastWriteTime:  d.LastWriteTime,
			FileSizeHigh:   d.FileSizeHigh,
			FileSizeLow:    d.FileSizeLow,
		},
		vol:   d.VolumeSerialNumber,
		idxhi: d.FileIndexHigh,
		idxlo: d.FileIndexLow,
		// fileStat.path is used by os.SameFile to decide if it needs
		// to fetch vol, idxhi and idxlo. But these are already set,
		// so set fileStat.path to "" to prevent os.SameFile doing it again.
		// Also do not set fileStat.filetype, because it is only used for
		// console and stdin/stdout. But you cannot call os.Stat for these.
	}, nil
}

// statWithFindFirstFile is used by Stat to handle special case of statting
// c:\pagefile.sys. We might discover that other files need similar treatment.
func statWithFindFirstFile(name string, namep *uint16) (FileInfo, error) {
	var fd syscall.Win32finddata
	h, err := syscall.FindFirstFile(namep, &fd)
	if err != nil {
		return nil, &PathError{"FindFirstFile", name, err}
	}
	syscall.FindClose(h)

	fullpath := name
	if !isAbs(fullpath) {
		fullpath, err = syscall.FullPath(fullpath)
		if err != nil {
			return nil, &PathError{"FullPath", name, err}
		}
	}
	return &fileStat{
		name: basename(name),
		path: fullpath,
		sys: syscall.Win32FileAttributeData{
			FileAttributes: fd.FileAttributes,
			CreationTime:   fd.CreationTime,
			LastAccessTime: fd.LastAccessTime,
			LastWriteTime:  fd.LastWriteTime,
			FileSizeHigh:   fd.FileSizeHigh,
			FileSizeLow:    fd.FileSizeLow,
		},
	}, nil
}

// lstatNolog implements Lstat for Windows.
func lstatNolog(name string) (FileInfo, error) {
	if len(name) == 0 {
		return nil, &PathError{"Lstat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
	}
	if name == DevNull {
		return &devNullStat, nil
	}
	fs := &fileStat{name: basename(name)}
	namep, e := syscall.UTF16PtrFromString(fixLongPath(name))
	if e != nil {
		return nil, &PathError{"Lstat", name, e}
	}
	e = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fs.sys)))
	if e != nil {
		if e != windows.ERROR_SHARING_VIOLATION {
			return nil, &PathError{"GetFileAttributesEx", name, e}
		}
		// try FindFirstFile now that GetFileAttributesEx failed
		return statWithFindFirstFile(name, namep)
	}
	fs.path = name
	if !isAbs(fs.path) {
		fs.path, e = syscall.FullPath(fs.path)
		if e != nil {
			return nil, &PathError{"FullPath", name, e}
		}
	}
	return fs, nil
}
