// Copyright 2020 CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#noformat

-- in.cue --
import "path"

#OSes: [path.Unix, path.Windows, path.Plan9]
#AnyOS: or(#OSes)

// Test these OSes for all tests below.
{
    [string]: {
        unix:    _
        plan9:   _
        windows: _
    }
}

Split: [OS=#AnyOS]: [ARG=string]: path.Split(ARG, OS)
Split: default:     [ARG=string]: path.Split(ARG)
Split: default:     Split.unix
Split: [_]: {
    "/foo/bar/baz":       _
    "a/b":                _
    "//host/share/foo":   _
    #"\\host\share\foo"#: _
    "c:/foo/bar":         _
    #"c:\foo\bar"#:       _
}

SplitList: [OS=string]: [ARG=string]: path.SplitList(ARG, OS)
SplitList: [_]: {
    "a:b":      _
    "a\u0000b": _
    "a;b":      _
}

Clean: [OS=#AnyOS]: [ARG=string]: path.Clean(ARG, OS)
Clean: default:     [ARG=string]: path.Clean(ARG)
Clean: default:     Clean.unix
Clean: [_]: {
    "abc//def//ghi":      _
    #"c:\abc\def\..\.."#: _
}

Match: [OS=#AnyOS]: [Pattern=string]: [Name=string]: path.Match(Pattern, Name, OS)
Match: default: [Pattern=string]: [Name=string]: path.Match(Pattern, Name)
Match: default: Match.unix
Match: [_]: {
    "*c":    "abc":               _
    "*.txt": "a/b.txt":           _
    "*.zip": #"c:\a\b\file.zip"#: _
}

Slash: [OS=string]: [ARG=string]: {
    to:   path.ToSlash(ARG, OS)
    from: path.FromSlash(ARG, OS)

    // should roundtrip
    to:   path.ToSlash(from, OS)
    from: path.FromSlash(to, OS)
}
Slash: [_]: {
    "":      _
    "/":     _
    "/a/b":  _
    "/a//b": _
}

Ext: [OS=#AnyOS]: [ARG=string]: path.Ext(ARG, OS)
Ext: default:     [ARG=string]: path.Ext(ARG)
Ext: default:     Ext.unix
Ext: [_]: {
    // Same for all OS-es
    "path.go":    ".go"
    "path.pb.go": ".go"
    "a.dir/b":    ""
    "a.dir/b.go": ".go"
    "a.dir/":     ""

    // Differs on Windows.
    "a.dir\\foo": _
}

Resolve: [OS=#AnyOS]: [A1=_]: [A2=_]: path.Resolve(A1, A2, OS)
Resolve: default:     [A1=_]: [A2=_]: path.Resolve(A1, A2)
Resolve: default:     Resolve.unix
Resolve: [_]: {
    "a/b/c": "d/e":   _
    "/a/b":  "/c/d":  _
    "c:/a":  #"d:\"#: _

    "//home/user/foo": "bar":             _
    "//home/user/foo": "//other/abs/foo": _
}

IsAbs: [OS=#AnyOS]: [ARG=string]: path.IsAbs(ARG, OS)
IsAbs: default:     [ARG=string]: path.IsAbs(ARG)
IsAbs: default:     IsAbs.unix
IsAbs: [_]: {
    "":     _
    "/a":   _
    "a":    _
    "c:":   _
    "c:/":  _
    "c:\\": _

    "//home/user/foo": _
}


Volume: [OS=string]:   [ARG=string]: path.VolumeName(ARG, OS)
Volume: [!="windows"]: [string]:     "" // non-windows is always ""
Volume: [_]: {
    "c:/foo/bar": _
    "c:":         _
    "2:":         _
    "":           _

    #"\\\host"#:          _
    #"\\\host\"#:         _
    #"\\\host\share"#:    _
    #"\\\host\\share"#:   _
    #"\\host"#:           _
    #"//host"#:           _
    #"\\host\"#:          _
    #"//host/"#:          _
    #"\\host\share"#:     _
    #"//host/share"#:     _
    #"\\host\share\"#:    _
    #"//host/share/"#:    _
    #"\\host\share\foo"#: _
    #"//host/share/foo"#: _

    #"\\host\share\\foo\\\bar\\\\baz"#: _
    #"//host/share//foo///bar////baz"#: _
    #"\\host\share\foo\..\bar"#:        _
    #"//host/share/foo/../bar"#:        _
}

-- out/path --
#OSes: ["unix", "windows", "plan9"]
#AnyOS: "unix" | "windows" | "plan9"
Split: {
	unix: {
		"/foo/bar/baz": ["/foo/bar/", "baz"]
		"a/b": ["a/", "b"]
		"//host/share/foo": ["//host/share/", "foo"]
		"\\\\host\\share\\foo": ["", "\\\\host\\share\\foo"]
		"c:/foo/bar": ["c:/foo/", "bar"]
		"c:\\foo\\bar": ["", "c:\\foo\\bar"]
	}
	plan9: {
		"/foo/bar/baz": ["/foo/bar/", "baz"]
		"a/b": ["a/", "b"]
		"//host/share/foo": ["//host/share/", "foo"]
		"\\\\host\\share\\foo": ["", "\\\\host\\share\\foo"]
		"c:/foo/bar": ["c:/foo/", "bar"]
		"c:\\foo\\bar": ["", "c:\\foo\\bar"]
	}
	windows: {
		"/foo/bar/baz": ["/foo/bar/", "baz"]
		"a/b": ["a/", "b"]
		"//host/share/foo": ["//host/share/", "foo"]
		"\\\\host\\share\\foo": ["\\\\host\\share\\", "foo"]
		"c:/foo/bar": ["c:/foo/", "bar"]
		"c:\\foo\\bar": ["c:\\foo\\", "bar"]
	}
	default: {
		"/foo/bar/baz": ["/foo/bar/", "baz"]
		"a/b": ["a/", "b"]
		"//host/share/foo": ["//host/share/", "foo"]
		"\\\\host\\share\\foo": ["", "\\\\host\\share\\foo"]
		"c:/foo/bar": ["c:/foo/", "bar"]
		"c:\\foo\\bar": ["", "c:\\foo\\bar"]
	}
}
SplitList: {
	unix: {
		"a:b": ["a", "b"]
		"a\u0000b": ["a\u0000b"]
		"a;b": ["a;b"]
	}
	plan9: {
		"a:b": ["a:b"]
		"a\u0000b": ["a", "b"]
		"a;b": ["a;b"]
	}
	windows: {
		"a:b": ["a:b"]
		"a\u0000b": ["a\u0000b"]
		"a;b": ["a", "b"]
	}
}
Clean: {
	unix: {
		"abc//def//ghi":        "abc/def/ghi"
		"c:\\abc\\def\\..\\..": "c:\\abc\\def\\..\\.."
	}
	plan9: {
		"abc//def//ghi":        "abc/def/ghi"
		"c:\\abc\\def\\..\\..": "c:\\abc\\def\\..\\.."
	}
	windows: {
		"abc//def//ghi":        "abc\\def\\ghi"
		"c:\\abc\\def\\..\\..": "c:\\"
	}
	default: {
		"abc//def//ghi":        "abc/def/ghi"
		"c:\\abc\\def\\..\\..": "c:\\abc\\def\\..\\.."
	}
}
Match: {
	unix: {
		"*c": {
			abc: true
		}
		"*.txt": {
			"a/b.txt": false
		}
		"*.zip": {
			"c:\\a\\b\\file.zip": true
		}
	}
	plan9: {
		"*c": {
			abc: true
		}
		"*.txt": {
			"a/b.txt": false
		}
		"*.zip": {
			"c:\\a\\b\\file.zip": true
		}
	}
	windows: {
		"*c": {
			abc: true
		}
		"*.txt": {
			"a/b.txt": true
		}
		"*.zip": {
			"c:\\a\\b\\file.zip": false
		}
	}
	default: {
		"*c": {
			abc: true
		}
		"*.txt": {
			"a/b.txt": false
		}
		"*.zip": {
			"c:\\a\\b\\file.zip": true
		}
	}
}
Slash: {
	unix: {
		"": {
			// should roundtrip
			to:   ""
			from: ""
		}
		"/": {
			// should roundtrip
			to:   "/"
			from: "/"
		}
		"/a/b": {
			// should roundtrip
			to:   "/a/b"
			from: "/a/b"
		}
		"/a//b": {
			// should roundtrip
			to:   "/a//b"
			from: "/a//b"
		}
	}
	plan9: {
		"": {
			// should roundtrip
			to:   ""
			from: ""
		}
		"/": {
			// should roundtrip
			to:   "/"
			from: "/"
		}
		"/a/b": {
			// should roundtrip
			to:   "/a/b"
			from: "/a/b"
		}
		"/a//b": {
			// should roundtrip
			to:   "/a//b"
			from: "/a//b"
		}
	}
	windows: {
		"": {
			// should roundtrip
			to:   ""
			from: ""
		}
		"/": {
			// should roundtrip
			to:   "/"
			from: "\\"
		}
		"/a/b": {
			// should roundtrip
			to:   "/a/b"
			from: "\\a\\b"
		}
		"/a//b": {
			// should roundtrip
			to:   "/a//b"
			from: "\\a\\\\b"
		}
	}
}
Ext: {
	unix: {
		// Same for all OS-es
		"path.go":    ".go"
		"path.pb.go": ".go"
		"a.dir/b":    ""
		"a.dir/b.go": ".go"
		"a.dir/":     ""

		// Differs on Windows.
		"a.dir\\foo": ".dir\\foo"
	}
	plan9: {
		// Same for all OS-es
		"path.go":    ".go"
		"path.pb.go": ".go"
		"a.dir/b":    ""
		"a.dir/b.go": ".go"
		"a.dir/":     ""

		// Differs on Windows.
		"a.dir\\foo": ".dir\\foo"
	}
	windows: {
		// Same for all OS-es
		"path.go":    ".go"
		"path.pb.go": ".go"
		"a.dir/b":    ""
		"a.dir/b.go": ".go"
		"a.dir/":     ""

		// Differs on Windows.
		"a.dir\\foo": ""
	}
	default: {
		// Same for all OS-es
		"path.go":    ".go"
		"path.pb.go": ".go"
		"a.dir/b":    ""
		"a.dir/b.go": ".go"
		"a.dir/":     ""

		// Differs on Windows.
		"a.dir\\foo": ".dir\\foo"
	}
}
Resolve: {
	unix: {
		"a/b/c": {
			"d/e": "a/b/c/d/e"
		}
		"/a/b": {
			"/c/d": "/c/d"
		}
		"c:/a": {
			"d:\\": "c:/a/d:\\"
		}
		"//home/user/foo": {
			bar:               "/home/user/foo/bar"
			"//other/abs/foo": "/other/abs/foo"
		}
	}
	plan9: {
		"a/b/c": {
			"d/e": "a/b/c/d/e"
		}
		"/a/b": {
			"/c/d": "/c/d"
		}
		"c:/a": {
			"d:\\": "c:/a/d:\\"
		}
		"//home/user/foo": {
			bar:               "/home/user/foo/bar"
			"//other/abs/foo": "/other/abs/foo"
		}
	}
	windows: {
		"a/b/c": {
			"d/e": "a\\b\\c\\d\\e"
		}
		"/a/b": {
			"/c/d": "\\a\\b\\c\\d"
		}
		"c:/a": {
			"d:\\": "d:\\"
		}
		"//home/user/foo": {
			bar:               "\\\\home\\user\\foo\\bar"
			"//other/abs/foo": "\\\\other\\abs\\foo"
		}
	}
	default: {
		"a/b/c": {
			"d/e": "a/b/c/d/e"
		}
		"/a/b": {
			"/c/d": "/c/d"
		}
		"c:/a": {
			"d:\\": "c:/a/d:\\"
		}
		"//home/user/foo": {
			"//other/abs/foo": "/other/abs/foo"
			bar:               "/home/user/foo/bar"
		}
	}
}
IsAbs: {
	unix: {
		"":                false
		"/a":              true
		a:                 false
		"c:":              false
		"c:/":             false
		"c:\\":            false
		"//home/user/foo": true
	}
	plan9: {
		"":                false
		"/a":              true
		a:                 false
		"c:":              false
		"c:/":             false
		"c:\\":            false
		"//home/user/foo": true
	}
	windows: {
		"":                false
		"/a":              false
		a:                 false
		"c:":              false
		"c:/":             true
		"c:\\":            true
		"//home/user/foo": true
	}
	default: {
		"":                false
		"/a":              true
		a:                 false
		"c:":              false
		"c:/":             false
		"c:\\":            false
		"//home/user/foo": true
	}
}
Volume: {
	unix: {
		"c:/foo/bar":                                 ""
		"c:":                                         ""
		"2:":                                         ""
		"":                                           ""
		"\\\\\\host":                                 ""
		"\\\\\\host\\":                               ""
		"\\\\\\host\\share":                          ""
		"\\\\\\host\\\\share":                        ""
		"\\\\host":                                   ""
		"//host":                                     ""
		"\\\\host\\":                                 ""
		"//host/":                                    ""
		"\\\\host\\share":                            ""
		"//host/share":                               ""
		"\\\\host\\share\\":                          ""
		"//host/share/":                              ""
		"\\\\host\\share\\foo":                       ""
		"//host/share/foo":                           ""
		"\\\\host\\share\\\\foo\\\\\\bar\\\\\\\\baz": ""
		"//host/share//foo///bar////baz":             ""
		"\\\\host\\share\\foo\\..\\bar":              ""
		"//host/share/foo/../bar":                    ""
	}
	plan9: {
		"c:/foo/bar":                                 ""
		"c:":                                         ""
		"2:":                                         ""
		"":                                           ""
		"\\\\\\host":                                 ""
		"\\\\\\host\\":                               ""
		"\\\\\\host\\share":                          ""
		"\\\\\\host\\\\share":                        ""
		"\\\\host":                                   ""
		"//host":                                     ""
		"\\\\host\\":                                 ""
		"//host/":                                    ""
		"\\\\host\\share":                            ""
		"//host/share":                               ""
		"\\\\host\\share\\":                          ""
		"//host/share/":                              ""
		"\\\\host\\share\\foo":                       ""
		"//host/share/foo":                           ""
		"\\\\host\\share\\\\foo\\\\\\bar\\\\\\\\baz": ""
		"//host/share//foo///bar////baz":             ""
		"\\\\host\\share\\foo\\..\\bar":              ""
		"//host/share/foo/../bar":                    ""
	}
	windows: {
		"c:/foo/bar":                                 "c:"
		"c:":                                         "c:"
		"2:":                                         ""
		"":                                           ""
		"\\\\\\host":                                 ""
		"\\\\\\host\\":                               ""
		"\\\\\\host\\share":                          ""
		"\\\\\\host\\\\share":                        ""
		"\\\\host":                                   ""
		"//host":                                     ""
		"\\\\host\\":                                 ""
		"//host/":                                    ""
		"\\\\host\\share":                            "\\\\host\\share"
		"//host/share":                               "//host/share"
		"\\\\host\\share\\":                          "\\\\host\\share"
		"//host/share/":                              "//host/share"
		"\\\\host\\share\\foo":                       "\\\\host\\share"
		"//host/share/foo":                           "//host/share"
		"\\\\host\\share\\\\foo\\\\\\bar\\\\\\\\baz": "\\\\host\\share"
		"//host/share//foo///bar////baz":             "//host/share"
		"\\\\host\\share\\foo\\..\\bar":              "\\\\host\\share"
		"//host/share/foo/../bar":                    "//host/share"
	}
}
