# Database Schema - Database configurations for provisioning
# Version: 1.0.0

{
  # SQLite configuration
  SqliteConfig = {
    database_path
      | String
      | doc "Path to SQLite database file"
      | {
        label = "valid path",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 256
      }
      | default = "./data/app.db",

    journal_mode
      | [| 'WAL, 'DELETE, 'TRUNCATE, 'PERSIST, 'MEMORY |]
      | doc "SQLite journal mode"
      | default = 'WAL,

    synchronous
      | [| 'OFF, 'NORMAL, 'FULL, 'EXTRA |]
      | doc "SQLite synchronous mode"
      | default = 'NORMAL,

    cache_size
      | Number
      | doc "Cache size in pages (negative for KB)"
      | default = -2000,

    foreign_keys
      | Bool
      | doc "Enable foreign key constraints"
      | default = true,
  },

  # PostgreSQL configuration
  PostgresConfig = {
    host
      | String
      | doc "PostgreSQL server hostname"
      | {
        label = "valid hostname",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 256
      }
      | default = "localhost",

    port
      | Number
      | doc "PostgreSQL server port (1024-65535)"
      | {
        label = "valid port",
        predicate = fun p => p >= 1024 && p <= 65535
      }
      | default = 5432,

    database
      | String
      | doc "Database name"
      | {
        label = "valid database name",
        predicate = fun s =>
          std.string.is_match "^[a-zA-Z0-9_]+$" s &&
          std.string.length s >= 1 && std.string.length s <= 64
      },

    username
      | String
      | doc "Database username"
      | {
        label = "valid username",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 64
      },

    password
      | String
      | doc "Database password (8-128 characters)"
      | {
        label = "valid password",
        predicate = fun s => std.string.length s >= 8 && std.string.length s <= 128
      },

    pool_size
      | Number
      | doc "Connection pool size (1-1000)"
      | {
        label = "valid pool size",
        predicate = fun n => n >= 1 && n <= 1000
      }
      | default = 10,

    connection_timeout
      | Number
      | doc "Connection timeout in seconds (1-300)"
      | {
        label = "valid timeout",
        predicate = fun n => n >= 1 && n <= 300
      }
      | default = 30,

    idle_timeout
      | Number
      | doc "Idle connection timeout in seconds (60-3600)"
      | {
        label = "valid idle timeout",
        predicate = fun n => n >= 60 && n <= 3600
      }
      | default = 600,

    max_lifetime
      | Number
      | doc "Maximum connection lifetime in seconds (300-86400)"
      | {
        label = "valid max lifetime",
        predicate = fun n => n >= 300 && n <= 86400
      }
      | default = 3600,

    ssl_mode
      | [| 'disable, 'allow, 'prefer, 'require, 'verify-ca, 'verify-full |]
      | doc "SSL mode for connections"
      | default = 'prefer,

    application_name
      | String
      | doc "Application name for connection tracking"
      | optional,
  },

  # MySQL configuration
  MysqlConfig = {
    host
      | String
      | doc "MySQL server hostname"
      | {
        label = "valid hostname",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 256
      }
      | default = "localhost",

    port
      | Number
      | doc "MySQL server port (1024-65535)"
      | {
        label = "valid port",
        predicate = fun p => p >= 1024 && p <= 65535
      }
      | default = 3306,

    database
      | String
      | doc "Database name"
      | {
        label = "valid database name",
        predicate = fun s =>
          std.string.is_match "^[a-zA-Z0-9_]+$" s &&
          std.string.length s >= 1 && std.string.length s <= 64
      },

    username
      | String
      | doc "Database username"
      | {
        label = "valid username",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 32
      },

    password
      | String
      | doc "Database password (8-128 characters)"
      | {
        label = "valid password",
        predicate = fun s => std.string.length s >= 8 && std.string.length s <= 128
      },

    pool_size
      | Number
      | doc "Connection pool size (1-1000)"
      | {
        label = "valid pool size",
        predicate = fun n => n >= 1 && n <= 1000
      }
      | default = 10,

    connection_timeout
      | Number
      | doc "Connection timeout in seconds (1-300)"
      | {
        label = "valid timeout",
        predicate = fun n => n >= 1 && n <= 300
      }
      | default = 30,

    charset
      | String
      | doc "Character set for connections"
      | default = "utf8mb4",

    collation
      | String
      | doc "Collation for connections"
      | default = "utf8mb4_unicode_ci",
  },

  # SurrealDB configuration
  SurrealdbConfig = {
    host
      | String
      | doc "SurrealDB server hostname"
      | {
        label = "valid hostname",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 256
      }
      | default = "localhost",

    port
      | Number
      | doc "SurrealDB server port (1024-65535)"
      | {
        label = "valid port",
        predicate = fun p => p >= 1024 && p <= 65535
      }
      | default = 8000,

    namespace
      | String
      | doc "SurrealDB namespace"
      | {
        label = "valid namespace",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 64
      },

    database
      | String
      | doc "Database name"
      | {
        label = "valid database name",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 64
      },

    username
      | String
      | doc "Database username"
      | {
        label = "valid username",
        predicate = fun s => std.string.length s >= 1 && std.string.length s <= 64
      },

    password
      | String
      | doc "Database password (8-128 characters)"
      | {
        label = "valid password",
        predicate = fun s => std.string.length s >= 8 && std.string.length s <= 128
      },

    protocol
      | [| 'http, 'https, 'ws, 'wss |]
      | doc "Connection protocol"
      | default = 'http,
  },

  # Main database configuration
  DatabaseConfig = {
    type
      | [| 'sqlite, 'postgres, 'mysql, 'surrealdb, 'none |]
      | doc "Database type to use",

    sqlite
      | SqliteConfig
      | doc "SQLite configuration"
      | optional,

    postgres
      | PostgresConfig
      | doc "PostgreSQL configuration"
      | optional,

    mysql
      | MysqlConfig
      | doc "MySQL configuration"
      | optional,

    surrealdb
      | SurrealdbConfig
      | doc "SurrealDB configuration"
      | optional,

    migrations_path
      | String
      | doc "Path to database migrations directory"
      | default = "./migrations",

    auto_migrate
      | Bool
      | doc "Automatically run migrations on startup"
      | default = false,
  },
}
