package volume

import (
	"errors"
	"fmt"
	"os"
	"regexp"
	"runtime"
	"strings"

	"github.com/docker/docker/api/types/mount"
	"github.com/docker/docker/pkg/stringid"
)

type windowsParser struct {
}

const (
	// Spec should be in the format [source:]destination[:mode]
	//
	// Examples: c:\foo bar:d:rw
	//           c:\foo:d:\bar
	//           myname:d:
	//           d:\
	//
	// Explanation of this regex! Thanks @thaJeztah on IRC and gist for help. See
	// https://gist.github.com/thaJeztah/6185659e4978789fb2b2. A good place to
	// test is https://regex-golang.appspot.com/assets/html/index.html
	//
	// Useful link for referencing named capturing groups:
	// http://stackoverflow.com/questions/20750843/using-named-matches-from-go-regex
	//
	// There are three match groups: source, destination and mode.
	//

	// rxHostDir is the first option of a source
	rxHostDir = `(?:\\\\\?\\)?[a-z]:[\\/](?:[^\\/:*?"<>|\r\n]+[\\/]?)*`
	// rxName is the second option of a source
	rxName = `[^\\/:*?"<>|\r\n]+`

	// RXReservedNames are reserved names not possible on Windows
	rxReservedNames = `(con)|(prn)|(nul)|(aux)|(com[1-9])|(lpt[1-9])`

	// rxPipe is a named path pipe (starts with `\\.\pipe\`, possibly with / instead of \)
	rxPipe = `[/\\]{2}.[/\\]pipe[/\\][^:*?"<>|\r\n]+`
	// rxSource is the combined possibilities for a source
	rxSource = `((?P<source>((` + rxHostDir + `)|(` + rxName + `)|(` + rxPipe + `))):)?`

	// Source. Can be either a host directory, a name, or omitted:
	//  HostDir:
	//    -  Essentially using the folder solution from
	//       https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch08s18.html
	//       but adding case insensitivity.
	//    -  Must be an absolute path such as c:\path
	//    -  Can include spaces such as `c:\program files`
	//    -  And then followed by a colon which is not in the capture group
	//    -  And can be optional
	//  Name:
	//    -  Must not contain invalid NTFS filename characters (https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx)
	//    -  And then followed by a colon which is not in the capture group
	//    -  And can be optional

	// rxDestination is the regex expression for the mount destination
	rxDestination = `(?P<destination>((?:\\\\\?\\)?([a-z]):((?:[\\/][^\\/:*?"<>\r\n]+)*[\\/]?))|(` + rxPipe + `))`

	rxLCOWDestination = `(?P<destination>/(?:[^\\/:*?"<>\r\n]+[/]?)*)`
	// Destination (aka container path):
	//    -  Variation on hostdir but can be a drive followed by colon as well
	//    -  If a path, must be absolute. Can include spaces
	//    -  Drive cannot be c: (explicitly checked in code, not RegEx)

	// rxMode is the regex expression for the mode of the mount
	// Mode (optional):
	//    -  Hopefully self explanatory in comparison to above regex's.
	//    -  Colon is not in the capture group
	rxMode = `(:(?P<mode>(?i)ro|rw))?`
)

type mountValidator func(mnt *mount.Mount) error

func windowsSplitRawSpec(raw, destRegex string) ([]string, error) {
	specExp := regexp.MustCompile(`^` + rxSource + destRegex + rxMode + `$`)
	match := specExp.FindStringSubmatch(strings.ToLower(raw))

	// Must have something back
	if len(match) == 0 {
		return nil, errInvalidSpec(raw)
	}

	var split []string
	matchgroups := make(map[string]string)
	// Pull out the sub expressions from the named capture groups
	for i, name := range specExp.SubexpNames() {
		matchgroups[name] = strings.ToLower(match[i])
	}
	if source, exists := matchgroups["source"]; exists {
		if source != "" {
			split = append(split, source)
		}
	}
	if destination, exists := matchgroups["destination"]; exists {
		if destination != "" {
			split = append(split, destination)
		}
	}
	if mode, exists := matchgroups["mode"]; exists {
		if mode != "" {
			split = append(split, mode)
		}
	}
	// Fix #26329. If the destination appears to be a file, and the source is null,
	// it may be because we've fallen through the possible naming regex and hit a
	// situation where the user intention was to map a file into a container through
	// a local volume, but this is not supported by the platform.
	if matchgroups["source"] == "" && matchgroups["destination"] != "" {
		volExp := regexp.MustCompile(`^` + rxName + `$`)
		reservedNameExp := regexp.MustCompile(`^` + rxReservedNames + `$`)

		if volExp.MatchString(matchgroups["destination"]) {
			if reservedNameExp.MatchString(matchgroups["destination"]) {
				return nil, fmt.Errorf("volume name %q cannot be a reserved word for Windows filenames", matchgroups["destination"])
			}
		} else {

			exists, isDir, _ := currentFileInfoProvider.fileInfo(matchgroups["destination"])
			if exists && !isDir {
				return nil, fmt.Errorf("file '%s' cannot be mapped. Only directories can be mapped on this platform", matchgroups["destination"])

			}
		}
	}
	return split, nil
}

func windowsValidMountMode(mode string) bool {
	if mode == "" {
		return true
	}
	return rwModes[strings.ToLower(mode)]
}
func windowsValidateNotRoot(p string) error {
	p = strings.ToLower(strings.Replace(p, `/`, `\`, -1))
	if p == "c:" || p == `c:\` {
		return fmt.Errorf("destination path cannot be `c:` or `c:\\`: %v", p)
	}
	return nil
}

var windowsSpecificValidators mountValidator = func(mnt *mount.Mount) error {
	return windowsValidateNotRoot(mnt.Target)
}

func windowsValidateRegex(p, r string) error {
	if regexp.MustCompile(`^` + r + `$`).MatchString(strings.ToLower(p)) {
		return nil
	}
	return fmt.Errorf("invalid mount path: '%s'", p)
}
func windowsValidateAbsolute(p string) error {
	if err := windowsValidateRegex(p, rxDestination); err != nil {
		return fmt.Errorf("invalid mount path: '%s' mount path must be absolute", p)
	}
	return nil
}

func windowsDetectMountType(p string) mount.Type {
	if strings.HasPrefix(p, `\\.\pipe\`) {
		return mount.TypeNamedPipe
	} else if regexp.MustCompile(`^` + rxHostDir + `$`).MatchString(p) {
		return mount.TypeBind
	} else {
		return mount.TypeVolume
	}
}

func (p *windowsParser) ReadWrite(mode string) bool {
	return strings.ToLower(mode) != "ro"
}

// IsVolumeNameValid checks a volume name in a platform specific manner.
func (p *windowsParser) ValidateVolumeName(name string) error {
	nameExp := regexp.MustCompile(`^` + rxName + `$`)
	if !nameExp.MatchString(name) {
		return errors.New("invalid volume name")
	}
	nameExp = regexp.MustCompile(`^` + rxReservedNames + `$`)
	if nameExp.MatchString(name) {
		return fmt.Errorf("volume name %q cannot be a reserved word for Windows filenames", name)
	}
	return nil
}
func (p *windowsParser) validateMountConfig(mnt *mount.Mount) error {
	return p.validateMountConfigReg(mnt, rxDestination, windowsSpecificValidators)
}

type fileInfoProvider interface {
	fileInfo(path string) (exist, isDir bool, err error)
}

type defaultFileInfoProvider struct {
}

func (defaultFileInfoProvider) fileInfo(path string) (exist, isDir bool, err error) {
	fi, err := os.Stat(path)
	if err != nil {
		if !os.IsNotExist(err) {
			return false, false, err
		}
		return false, false, nil
	}
	return true, fi.IsDir(), nil
}

var currentFileInfoProvider fileInfoProvider = defaultFileInfoProvider{}

func (p *windowsParser) validateMountConfigReg(mnt *mount.Mount, destRegex string, additionalValidators ...mountValidator) error {

	for _, v := range additionalValidators {
		if err := v(mnt); err != nil {
			return &errMountConfig{mnt, err}
		}
	}
	if len(mnt.Target) == 0 {
		return &errMountConfig{mnt, errMissingField("Target")}
	}

	if err := windowsValidateRegex(mnt.Target, destRegex); err != nil {
		return &errMountConfig{mnt, err}
	}

	switch mnt.Type {
	case mount.TypeBind:
		if len(mnt.Source) == 0 {
			return &errMountConfig{mnt, errMissingField("Source")}
		}
		// Don't error out just because the propagation mode is not supported on the platform
		if opts := mnt.BindOptions; opts != nil {
			if len(opts.Propagation) > 0 {
				return &errMountConfig{mnt, fmt.Errorf("invalid propagation mode: %s", opts.Propagation)}
			}
		}
		if mnt.VolumeOptions != nil {
			return &errMountConfig{mnt, errExtraField("VolumeOptions")}
		}

		if err := windowsValidateAbsolute(mnt.Source); err != nil {
			return &errMountConfig{mnt, err}
		}

		exists, isdir, err := currentFileInfoProvider.fileInfo(mnt.Source)
		if err != nil {
			return &errMountConfig{mnt, err}
		}
		if !exists {
			return &errMountConfig{mnt, errBindNotExist}
		}
		if !isdir {
			return &errMountConfig{mnt, fmt.Errorf("source path must be a directory")}
		}

	case mount.TypeVolume:
		if mnt.BindOptions != nil {
			return &errMountConfig{mnt, errExtraField("BindOptions")}
		}

		if len(mnt.Source) == 0 && mnt.ReadOnly {
			return &errMountConfig{mnt, fmt.Errorf("must not set ReadOnly mode when using anonymous volumes")}
		}

		if len(mnt.Source) != 0 {
			if err := p.ValidateVolumeName(mnt.Source); err != nil {
				return &errMountConfig{mnt, err}
			}
		}
	case mount.TypeNamedPipe:
		if len(mnt.Source) == 0 {
			return &errMountConfig{mnt, errMissingField("Source")}
		}

		if mnt.BindOptions != nil {
			return &errMountConfig{mnt, errExtraField("BindOptions")}
		}

		if mnt.ReadOnly {
			return &errMountConfig{mnt, errExtraField("ReadOnly")}
		}

		if windowsDetectMountType(mnt.Source) != mount.TypeNamedPipe {
			return &errMountConfig{mnt, fmt.Errorf("'%s' is not a valid pipe path", mnt.Source)}
		}

		if windowsDetectMountType(mnt.Target) != mount.TypeNamedPipe {
			return &errMountConfig{mnt, fmt.Errorf("'%s' is not a valid pipe path", mnt.Target)}
		}
	default:
		return &errMountConfig{mnt, errors.New("mount type unknown")}
	}
	return nil
}
func (p *windowsParser) ParseMountRaw(raw, volumeDriver string) (*MountPoint, error) {
	return p.parseMountRaw(raw, volumeDriver, rxDestination, true, windowsSpecificValidators)
}

func (p *windowsParser) parseMountRaw(raw, volumeDriver, destRegex string, convertTargetToBackslash bool, additionalValidators ...mountValidator) (*MountPoint, error) {
	arr, err := windowsSplitRawSpec(raw, destRegex)
	if err != nil {
		return nil, err
	}

	var spec mount.Mount
	var mode string
	switch len(arr) {
	case 1:
		// Just a destination path in the container
		spec.Target = arr[0]
	case 2:
		if windowsValidMountMode(arr[1]) {
			// Destination + Mode is not a valid volume - volumes
			// cannot include a mode. e.g. /foo:rw
			return nil, errInvalidSpec(raw)
		}
		// Host Source Path or Name + Destination
		spec.Source = strings.Replace(arr[0], `/`, `\`, -1)
		spec.Target = arr[1]
	case 3:
		// HostSourcePath+DestinationPath+Mode
		spec.Source = strings.Replace(arr[0], `/`, `\`, -1)
		spec.Target = arr[1]
		mode = arr[2]
	default:
		return nil, errInvalidSpec(raw)
	}
	if convertTargetToBackslash {
		spec.Target = strings.Replace(spec.Target, `/`, `\`, -1)
	}

	if !windowsValidMountMode(mode) {
		return nil, errInvalidMode(mode)
	}

	spec.Type = windowsDetectMountType(spec.Source)
	spec.ReadOnly = !p.ReadWrite(mode)

	// cannot assume that if a volume driver is passed in that we should set it
	if volumeDriver != "" && spec.Type == mount.TypeVolume {
		spec.VolumeOptions = &mount.VolumeOptions{
			DriverConfig: &mount.Driver{Name: volumeDriver},
		}
	}

	if copyData, isSet := getCopyMode(mode, p.DefaultCopyMode()); isSet {
		if spec.VolumeOptions == nil {
			spec.VolumeOptions = &mount.VolumeOptions{}
		}
		spec.VolumeOptions.NoCopy = !copyData
	}

	mp, err := p.parseMountSpec(spec, destRegex, convertTargetToBackslash, additionalValidators...)
	if mp != nil {
		mp.Mode = mode
	}
	if err != nil {
		err = fmt.Errorf("%v: %v", errInvalidSpec(raw), err)
	}
	return mp, err
}

func (p *windowsParser) ParseMountSpec(cfg mount.Mount) (*MountPoint, error) {
	return p.parseMountSpec(cfg, rxDestination, true, windowsSpecificValidators)
}
func (p *windowsParser) parseMountSpec(cfg mount.Mount, destRegex string, convertTargetToBackslash bool, additionalValidators ...mountValidator) (*MountPoint, error) {
	if err := p.validateMountConfigReg(&cfg, destRegex, additionalValidators...); err != nil {
		return nil, err
	}
	mp := &MountPoint{
		RW:          !cfg.ReadOnly,
		Destination: cfg.Target,
		Type:        cfg.Type,
		Spec:        cfg,
	}
	if convertTargetToBackslash {
		mp.Destination = strings.Replace(cfg.Target, `/`, `\`, -1)
	}

	switch cfg.Type {
	case mount.TypeVolume:
		if cfg.Source == "" {
			mp.Name = stringid.GenerateNonCryptoID()
		} else {
			mp.Name = cfg.Source
		}
		mp.CopyData = p.DefaultCopyMode()

		if cfg.VolumeOptions != nil {
			if cfg.VolumeOptions.DriverConfig != nil {
				mp.Driver = cfg.VolumeOptions.DriverConfig.Name
			}
			if cfg.VolumeOptions.NoCopy {
				mp.CopyData = false
			}
		}
	case mount.TypeBind:
		mp.Source = strings.Replace(cfg.Source, `/`, `\`, -1)
	case mount.TypeNamedPipe:
		mp.Source = strings.Replace(cfg.Source, `/`, `\`, -1)
	}
	// cleanup trailing `\` except for paths like `c:\`
	if len(mp.Source) > 3 && mp.Source[len(mp.Source)-1] == '\\' {
		mp.Source = mp.Source[:len(mp.Source)-1]
	}
	if len(mp.Destination) > 3 && mp.Destination[len(mp.Destination)-1] == '\\' {
		mp.Destination = mp.Destination[:len(mp.Destination)-1]
	}
	return mp, nil
}

func (p *windowsParser) ParseVolumesFrom(spec string) (string, string, error) {
	if len(spec) == 0 {
		return "", "", fmt.Errorf("volumes-from specification cannot be an empty string")
	}

	specParts := strings.SplitN(spec, ":", 2)
	id := specParts[0]
	mode := "rw"

	if len(specParts) == 2 {
		mode = specParts[1]
		if !windowsValidMountMode(mode) {
			return "", "", errInvalidMode(mode)
		}

		// Do not allow copy modes on volumes-from
		if _, isSet := getCopyMode(mode, p.DefaultCopyMode()); isSet {
			return "", "", errInvalidMode(mode)
		}
	}
	return id, mode, nil
}

func (p *windowsParser) DefaultPropagationMode() mount.Propagation {
	return mount.Propagation("")
}

func (p *windowsParser) ConvertTmpfsOptions(opt *mount.TmpfsOptions, readOnly bool) (string, error) {
	return "", fmt.Errorf("%s does not support tmpfs", runtime.GOOS)
}
func (p *windowsParser) DefaultCopyMode() bool {
	return false
}
func (p *windowsParser) IsBackwardCompatible(m *MountPoint) bool {
	return false
}

func (p *windowsParser) ValidateTmpfsMountDestination(dest string) error {
	return errors.New("Platform does not support tmpfs")
}
