package hcsshim

import (
	"bufio"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"syscall"

	"github.com/Microsoft/go-winio"
)

var errorIterationCanceled = errors.New("")

var mutatedUtilityVMFiles = map[string]bool{
	`EFI\Microsoft\Boot\BCD`:      true,
	`EFI\Microsoft\Boot\BCD.LOG`:  true,
	`EFI\Microsoft\Boot\BCD.LOG1`: true,
	`EFI\Microsoft\Boot\BCD.LOG2`: true,
}

const (
	filesPath          = `Files`
	hivesPath          = `Hives`
	utilityVMPath      = `UtilityVM`
	utilityVMFilesPath = `UtilityVM\Files`
)

func openFileOrDir(path string, mode uint32, createDisposition uint32) (file *os.File, err error) {
	return winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createDisposition)
}

func makeLongAbsPath(path string) (string, error) {
	if strings.HasPrefix(path, `\\?\`) || strings.HasPrefix(path, `\\.\`) {
		return path, nil
	}
	if !filepath.IsAbs(path) {
		absPath, err := filepath.Abs(path)
		if err != nil {
			return "", err
		}
		path = absPath
	}
	if strings.HasPrefix(path, `\\`) {
		return `\\?\UNC\` + path[2:], nil
	}
	return `\\?\` + path, nil
}

func hasPathPrefix(p, prefix string) bool {
	return strings.HasPrefix(p, prefix) && len(p) > len(prefix) && p[len(prefix)] == '\\'
}

type fileEntry struct {
	path string
	fi   os.FileInfo
	err  error
}

type legacyLayerReader struct {
	root         string
	result       chan *fileEntry
	proceed      chan bool
	currentFile  *os.File
	backupReader *winio.BackupFileReader
}

// newLegacyLayerReader returns a new LayerReader that can read the Windows
// container layer transport format from disk.
func newLegacyLayerReader(root string) *legacyLayerReader {
	r := &legacyLayerReader{
		root:    root,
		result:  make(chan *fileEntry),
		proceed: make(chan bool),
	}
	go r.walk()
	return r
}

func readTombstones(path string) (map[string]([]string), error) {
	tf, err := os.Open(filepath.Join(path, "tombstones.txt"))
	if err != nil {
		return nil, err
	}
	defer tf.Close()
	s := bufio.NewScanner(tf)
	if !s.Scan() || s.Text() != "\xef\xbb\xbfVersion 1.0" {
		return nil, errors.New("Invalid tombstones file")
	}

	ts := make(map[string]([]string))
	for s.Scan() {
		t := filepath.Join(filesPath, s.Text()[1:]) // skip leading `\`
		dir := filepath.Dir(t)
		ts[dir] = append(ts[dir], t)
	}
	if err = s.Err(); err != nil {
		return nil, err
	}

	return ts, nil
}

func (r *legacyLayerReader) walkUntilCancelled() error {
	root, err := makeLongAbsPath(r.root)
	if err != nil {
		return err
	}

	r.root = root
	ts, err := readTombstones(r.root)
	if err != nil {
		return err
	}

	err = filepath.Walk(r.root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// Indirect fix for https://github.com/moby/moby/issues/32838#issuecomment-343610048.
		// Handle failure from what may be a golang bug in the conversion of
		// UTF16 to UTF8 in files which are left in the recycle bin. Os.Lstat
		// which is called by filepath.Walk will fail when a filename contains
		// unicode characters. Skip the recycle bin regardless which is goodness.
		if strings.HasPrefix(path, filepath.Join(r.root, `Files\$Recycle.Bin`)) {
			return filepath.SkipDir
		}

		if path == r.root || path == filepath.Join(r.root, "tombstones.txt") || strings.HasSuffix(path, ".$wcidirs$") {
			return nil
		}

		r.result <- &fileEntry{path, info, nil}
		if !<-r.proceed {
			return errorIterationCanceled
		}

		// List all the tombstones.
		if info.IsDir() {
			relPath, err := filepath.Rel(r.root, path)
			if err != nil {
				return err
			}
			if dts, ok := ts[relPath]; ok {
				for _, t := range dts {
					r.result <- &fileEntry{filepath.Join(r.root, t), nil, nil}
					if !<-r.proceed {
						return errorIterationCanceled
					}
				}
			}
		}
		return nil
	})
	if err == errorIterationCanceled {
		return nil
	}
	if err == nil {
		return io.EOF
	}
	return err
}

func (r *legacyLayerReader) walk() {
	defer close(r.result)
	if !<-r.proceed {
		return
	}

	err := r.walkUntilCancelled()
	if err != nil {
		for {
			r.result <- &fileEntry{err: err}
			if !<-r.proceed {
				return
			}
		}
	}
}

func (r *legacyLayerReader) reset() {
	if r.backupReader != nil {
		r.backupReader.Close()
		r.backupReader = nil
	}
	if r.currentFile != nil {
		r.currentFile.Close()
		r.currentFile = nil
	}
}

func findBackupStreamSize(r io.Reader) (int64, error) {
	br := winio.NewBackupStreamReader(r)
	for {
		hdr, err := br.Next()
		if err != nil {
			if err == io.EOF {
				err = nil
			}
			return 0, err
		}
		if hdr.Id == winio.BackupData {
			return hdr.Size, nil
		}
	}
}

func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.FileBasicInfo, err error) {
	r.reset()
	r.proceed <- true
	fe := <-r.result
	if fe == nil {
		err = errors.New("LegacyLayerReader closed")
		return
	}
	if fe.err != nil {
		err = fe.err
		return
	}

	path, err = filepath.Rel(r.root, fe.path)
	if err != nil {
		return
	}

	if fe.fi == nil {
		// This is a tombstone. Return a nil fileInfo.
		return
	}

	if fe.fi.IsDir() && hasPathPrefix(path, filesPath) {
		fe.path += ".$wcidirs$"
	}

	f, err := openFileOrDir(fe.path, syscall.GENERIC_READ, syscall.OPEN_EXISTING)
	if err != nil {
		return
	}
	defer func() {
		if f != nil {
			f.Close()
		}
	}()

	fileInfo, err = winio.GetFileBasicInfo(f)
	if err != nil {
		return
	}

	if !hasPathPrefix(path, filesPath) {
		size = fe.fi.Size()
		r.backupReader = winio.NewBackupFileReader(f, false)
		if path == hivesPath || path == filesPath {
			// The Hives directory has a non-deterministic file time because of the
			// nature of the import process. Use the times from System_Delta.
			var g *os.File
			g, err = os.Open(filepath.Join(r.root, hivesPath, `System_Delta`))
			if err != nil {
				return
			}
			attr := fileInfo.FileAttributes
			fileInfo, err = winio.GetFileBasicInfo(g)
			g.Close()
			if err != nil {
				return
			}
			fileInfo.FileAttributes = attr
		}

		// The creation time and access time get reset for files outside of the Files path.
		fileInfo.CreationTime = fileInfo.LastWriteTime
		fileInfo.LastAccessTime = fileInfo.LastWriteTime

	} else {
		// The file attributes are written before the backup stream.
		var attr uint32
		err = binary.Read(f, binary.LittleEndian, &attr)
		if err != nil {
			return
		}
		fileInfo.FileAttributes = uintptr(attr)
		beginning := int64(4)

		// Find the accurate file size.
		if !fe.fi.IsDir() {
			size, err = findBackupStreamSize(f)
			if err != nil {
				err = &os.PathError{Op: "findBackupStreamSize", Path: fe.path, Err: err}
				return
			}
		}

		// Return back to the beginning of the backup stream.
		_, err = f.Seek(beginning, 0)
		if err != nil {
			return
		}
	}

	r.currentFile = f
	f = nil
	return
}

func (r *legacyLayerReader) Read(b []byte) (int, error) {
	if r.backupReader == nil {
		if r.currentFile == nil {
			return 0, io.EOF
		}
		return r.currentFile.Read(b)
	}
	return r.backupReader.Read(b)
}

func (r *legacyLayerReader) Seek(offset int64, whence int) (int64, error) {
	if r.backupReader == nil {
		if r.currentFile == nil {
			return 0, errors.New("no current file")
		}
		return r.currentFile.Seek(offset, whence)
	}
	return 0, errors.New("seek not supported on this stream")
}

func (r *legacyLayerReader) Close() error {
	r.proceed <- false
	<-r.result
	r.reset()
	return nil
}

type pendingLink struct {
	Path, Target string
}

type legacyLayerWriter struct {
	root         string
	parentRoots  []string
	destRoot     string
	currentFile  *os.File
	backupWriter *winio.BackupFileWriter
	tombstones   []string
	pathFixed    bool
	HasUtilityVM bool
	uvmDi        []dirInfo
	addedFiles   map[string]bool
	PendingLinks []pendingLink
}

// newLegacyLayerWriter returns a LayerWriter that can write the contaler layer
// transport format to disk.
func newLegacyLayerWriter(root string, parentRoots []string, destRoot string) *legacyLayerWriter {
	return &legacyLayerWriter{
		root:        root,
		parentRoots: parentRoots,
		destRoot:    destRoot,
		addedFiles:  make(map[string]bool),
	}
}

func (w *legacyLayerWriter) init() error {
	if !w.pathFixed {
		path, err := makeLongAbsPath(w.root)
		if err != nil {
			return err
		}
		for i, p := range w.parentRoots {
			w.parentRoots[i], err = makeLongAbsPath(p)
			if err != nil {
				return err
			}
		}
		destPath, err := makeLongAbsPath(w.destRoot)
		if err != nil {
			return err
		}
		w.root = path
		w.destRoot = destPath
		w.pathFixed = true
	}
	return nil
}

func (w *legacyLayerWriter) initUtilityVM() error {
	if !w.HasUtilityVM {
		err := os.Mkdir(filepath.Join(w.destRoot, utilityVMPath), 0)
		if err != nil {
			return err
		}
		// Server 2016 does not support multiple layers for the utility VM, so
		// clone the utility VM from the parent layer into this layer. Use hard
		// links to avoid unnecessary copying, since most of the files are
		// immutable.
		err = cloneTree(filepath.Join(w.parentRoots[0], utilityVMFilesPath), filepath.Join(w.destRoot, utilityVMFilesPath), mutatedUtilityVMFiles)
		if err != nil {
			return fmt.Errorf("cloning the parent utility VM image failed: %s", err)
		}
		w.HasUtilityVM = true
	}
	return nil
}

func (w *legacyLayerWriter) reset() {
	if w.backupWriter != nil {
		w.backupWriter.Close()
		w.backupWriter = nil
	}
	if w.currentFile != nil {
		w.currentFile.Close()
		w.currentFile = nil
	}
}

// copyFileWithMetadata copies a file using the backup/restore APIs in order to preserve metadata
func copyFileWithMetadata(srcPath, destPath string, isDir bool) (fileInfo *winio.FileBasicInfo, err error) {
	createDisposition := uint32(syscall.CREATE_NEW)
	if isDir {
		err = os.Mkdir(destPath, 0)
		if err != nil {
			return nil, err
		}
		createDisposition = syscall.OPEN_EXISTING
	}

	src, err := openFileOrDir(srcPath, syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY, syscall.OPEN_EXISTING)
	if err != nil {
		return nil, err
	}
	defer src.Close()
	srcr := winio.NewBackupFileReader(src, true)
	defer srcr.Close()

	fileInfo, err = winio.GetFileBasicInfo(src)
	if err != nil {
		return nil, err
	}

	dest, err := openFileOrDir(destPath, syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY, createDisposition)
	if err != nil {
		return nil, err
	}
	defer dest.Close()

	err = winio.SetFileBasicInfo(dest, fileInfo)
	if err != nil {
		return nil, err
	}

	destw := winio.NewBackupFileWriter(dest, true)
	defer func() {
		cerr := destw.Close()
		if err == nil {
			err = cerr
		}
	}()

	_, err = io.Copy(destw, srcr)
	if err != nil {
		return nil, err
	}

	return fileInfo, nil
}

// cloneTree clones a directory tree using hard links. It skips hard links for
// the file names in the provided map and just copies those files.
func cloneTree(srcPath, destPath string, mutatedFiles map[string]bool) error {
	var di []dirInfo
	err := filepath.Walk(srcPath, func(srcFilePath string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		relPath, err := filepath.Rel(srcPath, srcFilePath)
		if err != nil {
			return err
		}
		destFilePath := filepath.Join(destPath, relPath)

		fileAttributes := info.Sys().(*syscall.Win32FileAttributeData).FileAttributes
		// Directories, reparse points, and files that will be mutated during
		// utility VM import must be copied. All other files can be hard linked.
		isReparsePoint := fileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0
		// In go1.9, FileInfo.IsDir() returns false if the directory is also a symlink.
		// See: https://github.com/golang/go/commit/1989921aef60c83e6f9127a8448fb5ede10e9acc
		// Fixes the problem by checking syscall.FILE_ATTRIBUTE_DIRECTORY directly
		isDir := fileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0

		if isDir || isReparsePoint || mutatedFiles[relPath] {
			fi, err := copyFileWithMetadata(srcFilePath, destFilePath, isDir)
			if err != nil {
				return err
			}
			if isDir && !isReparsePoint {
				di = append(di, dirInfo{path: destFilePath, fileInfo: *fi})
			}
		} else {
			err = os.Link(srcFilePath, destFilePath)
			if err != nil {
				return err
			}
		}

		// Don't recurse on reparse points in go1.8 and older. Filepath.Walk
		// handles this in go1.9 and newer.
		if isDir && isReparsePoint && shouldSkipDirectoryReparse {
			return filepath.SkipDir
		}

		return nil
	})
	if err != nil {
		return err
	}

	return reapplyDirectoryTimes(di)
}

func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) error {
	w.reset()
	err := w.init()
	if err != nil {
		return err
	}

	if name == utilityVMPath {
		return w.initUtilityVM()
	}

	if hasPathPrefix(name, utilityVMPath) {
		if !w.HasUtilityVM {
			return errors.New("missing UtilityVM directory")
		}
		if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
			return errors.New("invalid UtilityVM layer")
		}
		path := filepath.Join(w.destRoot, name)
		createDisposition := uint32(syscall.OPEN_EXISTING)
		if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
			st, err := os.Lstat(path)
			if err != nil && !os.IsNotExist(err) {
				return err
			}
			if st != nil {
				// Delete the existing file/directory if it is not the same type as this directory.
				existingAttr := st.Sys().(*syscall.Win32FileAttributeData).FileAttributes
				if (uint32(fileInfo.FileAttributes)^existingAttr)&(syscall.FILE_ATTRIBUTE_DIRECTORY|syscall.FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
					if err = os.RemoveAll(path); err != nil {
						return err
					}
					st = nil
				}
			}
			if st == nil {
				if err = os.Mkdir(path, 0); err != nil {
					return err
				}
			}
			if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
				w.uvmDi = append(w.uvmDi, dirInfo{path: path, fileInfo: *fileInfo})
			}
		} else {
			// Overwrite any existing hard link.
			err = os.Remove(path)
			if err != nil && !os.IsNotExist(err) {
				return err
			}
			createDisposition = syscall.CREATE_NEW
		}

		f, err := openFileOrDir(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY, createDisposition)
		if err != nil {
			return err
		}
		defer func() {
			if f != nil {
				f.Close()
				os.Remove(path)
			}
		}()

		err = winio.SetFileBasicInfo(f, fileInfo)
		if err != nil {
			return err
		}

		w.backupWriter = winio.NewBackupFileWriter(f, true)
		w.currentFile = f
		w.addedFiles[name] = true
		f = nil
		return nil
	}

	path := filepath.Join(w.root, name)
	if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
		err := os.Mkdir(path, 0)
		if err != nil {
			return err
		}
		path += ".$wcidirs$"
	}

	f, err := openFileOrDir(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.CREATE_NEW)
	if err != nil {
		return err
	}
	defer func() {
		if f != nil {
			f.Close()
			os.Remove(path)
		}
	}()

	strippedFi := *fileInfo
	strippedFi.FileAttributes = 0
	err = winio.SetFileBasicInfo(f, &strippedFi)
	if err != nil {
		return err
	}

	if hasPathPrefix(name, hivesPath) {
		w.backupWriter = winio.NewBackupFileWriter(f, false)
	} else {
		// The file attributes are written before the stream.
		err = binary.Write(f, binary.LittleEndian, uint32(fileInfo.FileAttributes))
		if err != nil {
			return err
		}
	}

	w.currentFile = f
	w.addedFiles[name] = true
	f = nil
	return nil
}

func (w *legacyLayerWriter) AddLink(name string, target string) error {
	w.reset()
	err := w.init()
	if err != nil {
		return err
	}

	var roots []string
	if hasPathPrefix(target, filesPath) {
		// Look for cross-layer hard link targets in the parent layers, since
		// nothing is in the destination path yet.
		roots = w.parentRoots
	} else if hasPathPrefix(target, utilityVMFilesPath) {
		// Since the utility VM is fully cloned into the destination path
		// already, look for cross-layer hard link targets directly in the
		// destination path.
		roots = []string{w.destRoot}
	}

	if roots == nil || (!hasPathPrefix(name, filesPath) && !hasPathPrefix(name, utilityVMFilesPath)) {
		return errors.New("invalid hard link in layer")
	}

	// Find to try the target of the link in a previously added file. If that
	// fails, search in parent layers.
	var selectedRoot string
	if _, ok := w.addedFiles[target]; ok {
		selectedRoot = w.destRoot
	} else {
		for _, r := range roots {
			if _, err = os.Lstat(filepath.Join(r, target)); err != nil {
				if !os.IsNotExist(err) {
					return err
				}
			} else {
				selectedRoot = r
				break
			}
		}
		if selectedRoot == "" {
			return fmt.Errorf("failed to find link target for '%s' -> '%s'", name, target)
		}
	}
	// The link can't be written until after the ImportLayer call.
	w.PendingLinks = append(w.PendingLinks, pendingLink{
		Path:   filepath.Join(w.destRoot, name),
		Target: filepath.Join(selectedRoot, target),
	})
	w.addedFiles[name] = true
	return nil
}

func (w *legacyLayerWriter) Remove(name string) error {
	if hasPathPrefix(name, filesPath) {
		w.tombstones = append(w.tombstones, name[len(filesPath)+1:])
	} else if hasPathPrefix(name, utilityVMFilesPath) {
		err := w.initUtilityVM()
		if err != nil {
			return err
		}
		// Make sure the path exists; os.RemoveAll will not fail if the file is
		// already gone, and this needs to be a fatal error for diagnostics
		// purposes.
		path := filepath.Join(w.destRoot, name)
		if _, err := os.Lstat(path); err != nil {
			return err
		}
		err = os.RemoveAll(path)
		if err != nil {
			return err
		}
	} else {
		return fmt.Errorf("invalid tombstone %s", name)
	}

	return nil
}

func (w *legacyLayerWriter) Write(b []byte) (int, error) {
	if w.backupWriter == nil {
		if w.currentFile == nil {
			return 0, errors.New("closed")
		}
		return w.currentFile.Write(b)
	}
	return w.backupWriter.Write(b)
}

func (w *legacyLayerWriter) Close() error {
	w.reset()
	err := w.init()
	if err != nil {
		return err
	}
	tf, err := os.Create(filepath.Join(w.root, "tombstones.txt"))
	if err != nil {
		return err
	}
	defer tf.Close()
	_, err = tf.Write([]byte("\xef\xbb\xbfVersion 1.0\n"))
	if err != nil {
		return err
	}
	for _, t := range w.tombstones {
		_, err = tf.Write([]byte(filepath.Join(`\`, t) + "\n"))
		if err != nil {
			return err
		}
	}
	if w.HasUtilityVM {
		err = reapplyDirectoryTimes(w.uvmDi)
		if err != nil {
			return err
		}
	}
	return nil
}
