package volume

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/system"
)

// read-write modes
var rwModes = map[string]bool{
	"rw": true,
}

// read-only modes
var roModes = map[string]bool{
	"ro": true,
}

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])`

	// RXSource is the combined possibilities for a source
	RXSource = `((?P<source>((` + RXHostDir + `)|(` + RXName + `))):)?`

	// 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]+)*\\?))`
	// 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
var RXMode string

func init() {
	osv := system.GetOSVersion()
	// Read-only volumes supported from 14350 onwards (post Windows Server 2016 TP5)
	// Mode (optional):
	//    -  Hopefully self explanatory in comparison to above regex's.
	//    -  Colon is not in the capture group
	if osv.Build >= 14350 {
		RXMode = `(:(?P<mode>(?i)ro|rw))?`
	} else {
		RXMode = `(:(?P<mode>(?i)rw))?`
	}
}

// BackwardsCompatible decides whether this mount point can be
// used in old versions of Docker or not.
// Windows volumes are never backwards compatible.
func (m *MountPoint) BackwardsCompatible() bool {
	return false
}

// ParseMountSpec validates the configuration of mount information is valid.
func ParseMountSpec(spec string, volumeDriver string) (*MountPoint, error) {
	var specExp = regexp.MustCompile(`^` + RXSource + RXDestination + RXMode + `$`)

	// Ensure in platform semantics for matching. The CLI will send in Unix semantics.
	match := specExp.FindStringSubmatch(filepath.FromSlash(strings.ToLower(spec)))

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

	// Pull out the sub expressions from the named capture groups
	matchgroups := make(map[string]string)
	for i, name := range specExp.SubexpNames() {
		matchgroups[name] = strings.ToLower(match[i])
	}

	mp := &MountPoint{
		Source:      matchgroups["source"],
		Destination: matchgroups["destination"],
		RW:          true,
	}
	if strings.ToLower(matchgroups["mode"]) == "ro" {
		mp.RW = false
	}

	// Volumes cannot include an explicitly supplied mode eg c:\path:rw
	if mp.Source == "" && mp.Destination != "" && matchgroups["mode"] != "" {
		return nil, errInvalidSpec(spec)
	}

	// Note: No need to check if destination is absolute as it must be by
	// definition of matching the regex.

	if filepath.VolumeName(mp.Destination) == mp.Destination {
		// Ensure the destination path, if a drive letter, is not the c drive
		if strings.ToLower(mp.Destination) == "c:" {
			return nil, fmt.Errorf("Destination drive letter in '%s' cannot be c:", spec)
		}
	} else {
		// So we know the destination is a path, not drive letter. Clean it up.
		mp.Destination = filepath.Clean(mp.Destination)
		// Ensure the destination path, if a path, is not the c root directory
		if strings.ToLower(mp.Destination) == `c:\` {
			return nil, fmt.Errorf(`Destination path in '%s' cannot be c:\`, spec)
		}
	}

	// See if the source is a name instead of a host directory
	if len(mp.Source) > 0 {
		validName, err := IsVolumeNameValid(mp.Source)
		if err != nil {
			return nil, err
		}
		if validName {
			// OK, so the source is a name.
			mp.Name = mp.Source
			mp.Source = ""

			// Set the driver accordingly
			mp.Driver = volumeDriver
			if len(mp.Driver) == 0 {
				mp.Driver = DefaultDriverName
			}
		} else {
			// OK, so the source must be a host directory. Make sure it's clean.
			mp.Source = filepath.Clean(mp.Source)
		}
	}

	// Ensure the host path source, if supplied, exists and is a directory
	if len(mp.Source) > 0 {
		var fi os.FileInfo
		var err error
		if fi, err = os.Stat(mp.Source); err != nil {
			return nil, fmt.Errorf("Source directory '%s' could not be found: %s", mp.Source, err)
		}
		if !fi.IsDir() {
			return nil, fmt.Errorf("Source '%s' is not a directory", mp.Source)
		}
	}

	logrus.Debugf("MP: Source '%s', Dest '%s', RW %t, Name '%s', Driver '%s'", mp.Source, mp.Destination, mp.RW, mp.Name, mp.Driver)
	return mp, nil
}

// IsVolumeNameValid checks a volume name in a platform specific manner.
func IsVolumeNameValid(name string) (bool, error) {
	nameExp := regexp.MustCompile(`^` + RXName + `$`)
	if !nameExp.MatchString(name) {
		return false, nil
	}
	nameExp = regexp.MustCompile(`^` + RXReservedNames + `$`)
	if nameExp.MatchString(name) {
		return false, fmt.Errorf("Volume name %q cannot be a reserved word for Windows filenames", name)
	}
	return true, nil
}

// ValidMountMode will make sure the mount mode is valid.
// returns if it's a valid mount mode or not.
func ValidMountMode(mode string) bool {
	return roModes[strings.ToLower(mode)] || rwModes[strings.ToLower(mode)]
}

// ReadWrite tells you if a mode string is a valid read-write mode or not.
func ReadWrite(mode string) bool {
	return rwModes[strings.ToLower(mode)]
}
