//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the container project authors. All rights reserved.
//
// 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
//
//   https://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.
//===----------------------------------------------------------------------===//

import Foundation
import Testing

@testable import ContainerClient

struct VolumeValidationTests {

    @Test("Valid volume names should pass validation")
    func testValidVolumeNames() {
        let validNames = [
            "a",  // Single alphanumeric
            "1",  // Single numeric
            "volume1",  // Alphanumeric
            "my-volume",  // With hyphen
            "my_volume",  // With underscore
            "my.volume",  // With period
            "volume-1.2_test",  // Mixed valid characters
            "1volume",  // Starting with number
            "Avolume",  // Starting with uppercase
            "a" + String(repeating: "x", count: 254),  // Max length (255)
        ]

        for name in validNames {
            #expect(VolumeStorage.isValidVolumeName(name), "'\(name)' should be valid")
        }
    }

    @Test("Invalid volume names should fail validation")
    func testInvalidVolumeNames() {
        let invalidNames = [
            "",  // Empty string
            ".volume",  // Starting with period
            "_volume",  // Starting with underscore
            "-volume",  // Starting with hyphen
            "volume@",  // Contains invalid character (@)
            "volume space",  // Contains space
            "volume/path",  // Contains slash
            "volume:tag",  // Contains colon
            "volume#hash",  // Contains hash
            "volume$",  // Contains dollar sign
            "volume!",  // Contains exclamation
            "volume%",  // Contains percent
            "volume*",  // Contains asterisk
            "volume+",  // Contains plus
            "volume=",  // Contains equals
            "volume[",  // Contains bracket
            "volume]",  // Contains bracket
            "volume{",  // Contains brace
            "volume}",  // Contains brace
            "volume|",  // Contains pipe
            "volume\\",  // Contains backslash
            "volume\"",  // Contains quote
            "volume'",  // Contains single quote
            "volume<",  // Contains less than
            "volume>",  // Contains greater than
            "volume?",  // Contains question mark
            "volume,",  // Contains comma
            "volume;",  // Contains semicolon
            "a" + String(repeating: "x", count: 255),  // Too long (256 chars)
        ]

        for name in invalidNames {
            #expect(!VolumeStorage.isValidVolumeName(name), "'\(name)' should be invalid")
        }
    }

    @Test("Edge cases for volume name validation")
    func testVolumeNameEdgeCases() {
        // Test exact boundary conditions
        #expect(VolumeStorage.isValidVolumeName("a"), "Single character should be valid")
        #expect(!VolumeStorage.isValidVolumeName(""), "Empty string should be invalid")

        // Test maximum length boundary
        let maxLengthName = String(repeating: "a", count: 255)
        let tooLongName = String(repeating: "a", count: 256)
        #expect(VolumeStorage.isValidVolumeName(maxLengthName), "255 character name should be valid")
        #expect(!VolumeStorage.isValidVolumeName(tooLongName), "256 character name should be invalid")

        // Test other edge cases
        #expect(VolumeStorage.isValidVolumeName("0volume"), "Name starting with digit should be valid")
        #expect(VolumeStorage.isValidVolumeName("Volume"), "Name starting with uppercase should be valid")
        #expect(!VolumeStorage.isValidVolumeName(".hidden"), "Name starting with period should be invalid")
        #expect(!VolumeStorage.isValidVolumeName("_private"), "Name starting with underscore should be invalid")
        #expect(!VolumeStorage.isValidVolumeName("-dash"), "Name starting with hyphen should be invalid")
    }

    @Test("Unicode and special character handling")
    func testUnicodeCharacters() {
        let unicodeNames = [
            "volume-ñ",  // Non-ASCII letter
            "volume-中文",  // Chinese characters
            "volume-🍎",  // Emoji
            "volume-café",  // Accented characters
            "αβγ",  // Greek letters
        ]

        for name in unicodeNames {
            #expect(!VolumeStorage.isValidVolumeName(name), "Unicode name '\(name)' should be invalid")
        }
    }

    @Test("Common Container volume name patterns")
    func testCommonVolumeNames() {
        let commonPatterns = [
            "myapp-data",  // Common app data volume
            "postgres_data",  // Database volume
            "nginx.conf",  // Config volume
            "logs-2024",  // Log volume with year
            "cache_redis_v1.2",  // Version-tagged cache
            "backup.daily",  // Backup volume
            "shared-storage",  // Shared volume
        ]

        for name in commonPatterns {
            #expect(VolumeStorage.isValidVolumeName(name), "Common volume name pattern '\(name)' should be valid")
        }
    }
}
