modules/devops/Write-Docker.ps1

param(
    [string]$ProjectName,
    [string]$OrmMode,
    [string]$DbProvider,
    [string]$OutputPath,
    [string]$FrontendMode,
    [string[]]$Entities,
    [switch]$SkipFrontend,
    [bool]$Observability = $false,
    [string]$Platform = "Web"
)

. (Join-Path (Split-Path $MyInvocation.MyCommand.Path) "..\core\Utils.ps1")

$dockerRoot = Join-Path $OutputPath "$ProjectName-docker"
if (-not $Global:DryRun -and -not (Test-Path $dockerRoot)) {
    New-Item -ItemType Directory -Path $dockerRoot -Force | Out-Null
}

function Write-File($f, $c) { Write-CoreFile (Join-Path $dockerRoot $f) $c }
function T($t) { $t.Replace("{P}", $ProjectName) }

$p = $ProjectName.ToLower()

# --- Connection String Helper ---
$dockerConnStr = switch ($DbProvider) {
    "Postgres" { "Host=db;Database=${ProjectName}Db;Username=postgres;Password=postgres" }
    default    { "Server=db,1433;Database=${ProjectName}Db;User Id=sa;Password=YourStrong@Passw0rd;TrustServerCertificate=True;" }
}

# --- Database Service Definition ---
$dbService = ""
if ($DbProvider -eq "MSSQL") {
    $dbService = @"
  db:
    container_name: ${p}-db
    build:
      context: ./sqlserver
    environment:
      SA_PASSWORD: "YourStrong@Passw0rd"
      ACCEPT_EULA: "Y"
    ports:
      - "1433:1433"
    healthcheck:
      test: ["CMD", "/opt/mssql-tools18/bin/sqlcmd", "-S", "localhost", "-U", "sa", "-P", "YourStrong@Passw0rd", "-Q", "SELECT 1", "-No"]
      interval: 10s
      timeout: 5s
      retries: 10
    volumes:
      - ${p}_data:/var/opt/mssql
"@

} elseif ($DbProvider -eq "Postgres") {
    $dbService = @"
  db:
    container_name: ${p}-db
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: ${ProjectName}Db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d ${ProjectName}Db"]
      interval: 5s
      timeout: 5s
      retries: 5
    volumes:
      - ${p}_data:/var/lib/postgresql/data
      - ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql
"@

}

# --- docker-compose.yml ---
$dockerComposeContent = @"
services:
$dbService
 
  api:
    container_name: ${p}-api
    build:
      context: ../$ProjectName-backend
      dockerfile: src/$ProjectName.WebApi/Dockerfile
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - ConnectionStrings__DefaultConnection=$dockerConnStr
      - Jwt__Key=your-super-secret-key-min-32-characters!!
      - Jwt__Issuer=${ProjectName}Api
      - Jwt__Audience=${ProjectName}Client
    ports:
      - "8080:8080"
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health || exit 1"]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    depends_on:
      db:
        condition: service_healthy
"@


if (-not $SkipFrontend -and $Platform -match "Web|Both") {
    $uiExternalPort = 3000
    $uiInternalPort = 80
    $uiContext = "../$ProjectName-web"
    
    $dockerComposeContent += @"
 
  ui:
    container_name: ${p}-ui
    build:
      context: $uiContext
      dockerfile: Dockerfile
    env_file:
      - $uiContext/.env.docker
    ports:
      - "${uiExternalPort}:${uiInternalPort}"
    depends_on:
      api:
        condition: service_healthy
"@

}

$dockerComposeContent += "`n`nvolumes:`n ${p}_data:"
Write-File "docker-compose.yml" $dockerComposeContent

# --- docker-compose.override.yml (Seq for Observability) ---
if ($Observability) {
    $override = @"
services:
  seq:
    image: datalust/seq:latest
    environment:
      ACCEPT_EULA: Y
    ports:
      - "5341:80"
      - "5342:5341"
 
  api:
    environment:
      - Serilog__WriteTo__0__Args__serverUrl=http://seq:5341
"@

    Write-File "docker-compose.override.yml" $override
}

# --- SQL Scripts ---
# EFCore/Hybrid: migration tabloları ve seed'i yönetir, init.sql sadece DB oluşturur
# Dapper: migration yok, init.sql tüm yapıyı kurar (idempotent)
$bcryptHash = '$2a$12$4V.u4DaYV9N7BPMkbHBtuO18JGY.AQWcGGb4c39EDBxZz9eQXlZRK'

$tables = ""
foreach ($e in $Entities) {
    $pE = Get-Plural $e
    $extraSql = if ($e -eq "Product") { ", Price DECIMAL(18,2) DEFAULT 0" } else { "" }

    if ($DbProvider -eq "Postgres") {
        if ($e -eq "User") {
            $tables += "CREATE TABLE IF NOT EXISTS Users (Id SERIAL PRIMARY KEY, Username VARCHAR(100) NOT NULL UNIQUE, PasswordHash VARCHAR(256) NOT NULL, Email VARCHAR(256), Role VARCHAR(50) DEFAULT 'User' NOT NULL, IsActive BOOLEAN DEFAULT TRUE, IsDeleted BOOLEAN DEFAULT FALSE, DeletedAt TIMESTAMP, CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UpdatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP);`n"
        } else {
            $tables += "CREATE TABLE IF NOT EXISTS $pE (Id SERIAL PRIMARY KEY, Name VARCHAR(200) NOT NULL$extraSql, IsDeleted BOOLEAN DEFAULT FALSE, DeletedAt TIMESTAMP, CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UpdatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP);`n"
        }
    } else {
        if ($e -eq "User") {
            $tables += "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='Users' AND xtype='U') CREATE TABLE Users (Id INT IDENTITY(1,1) PRIMARY KEY, Username NVARCHAR(100) NOT NULL UNIQUE, PasswordHash NVARCHAR(256) NOT NULL, Email NVARCHAR(256), Role NVARCHAR(50) DEFAULT 'User' NOT NULL, IsActive BIT DEFAULT 1, IsDeleted BIT DEFAULT 0, DeletedAt DATETIME2, CreatedAt DATETIME2 DEFAULT GETUTCDATE(), UpdatedAt DATETIME2 DEFAULT GETUTCDATE());`n"
        } else {
            $tables += "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='$pE' AND xtype='U') CREATE TABLE $pE (Id INT IDENTITY(1,1) PRIMARY KEY, Name NVARCHAR(200) NOT NULL$extraSql, IsDeleted BIT DEFAULT 0, DeletedAt DATETIME2, CreatedAt DATETIME2 DEFAULT GETUTCDATE(), UpdatedAt DATETIME2 DEFAULT GETUTCDATE());`n"
        }
    }
}

# --- DB-Specific Files ---
if ($DbProvider -eq "MSSQL") {
    $seedSql = $tables + @'
GO
-- Default Password: Admin123!
IF NOT EXISTS (SELECT 1 FROM Users WHERE Username='admin')
    INSERT INTO Users (Username, PasswordHash, Email, Role) VALUES ('admin', '$2a$12$4V.u4DaYV9N7BPMkbHBtuO18JGY.AQWcGGb4c39EDBxZz9eQXlZRK', 'admin@example.com', 'Admin');
GO
'@


    $initSql = (T @'
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'{P}Db') CREATE DATABASE [{P}Db];
GO
USE [{P}Db];
GO
'@
) + "`n" + $seedSql

    if (-not $Global:DryRun) {
        New-Item -ItemType Directory -Path (Join-Path $dockerRoot "sqlserver") -Force | Out-Null
    }
    Write-CoreFile (Join-Path $dockerRoot "sqlserver\Dockerfile") "FROM mcr.microsoft.com/mssql/server:2022-latest`nENV ACCEPT_EULA=Y`nENV SA_PASSWORD=`"YourStrong@Passw0rd`"`nCOPY init.sql /init.sql`nCOPY --chmod=755 entrypoint.sh /entrypoint.sh`nENTRYPOINT [`"/entrypoint.sh`"]"
    Write-CoreFile (Join-Path $dockerRoot "sqlserver\entrypoint.sh") (T "#!/bin/bash`n/opt/mssql/bin/sqlservr &`nsleep 30`n/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P `"YourStrong@Passw0rd`" -i /init.sql -No`nwait")
    Write-CoreFile (Join-Path $dockerRoot "sqlserver\init.sql") $initSql

} elseif ($DbProvider -eq "Postgres") {
    $initSql = $tables + "`n-- Default Password: Admin123!`nINSERT INTO Users (Username, PasswordHash, Email, Role) VALUES ('admin', '$bcryptHash', 'admin@example.com', 'Admin') ON CONFLICT (Username) DO NOTHING;"
    if (-not $Global:DryRun) {
        New-Item -ItemType Directory -Path (Join-Path $dockerRoot "postgresql") -Force | Out-Null
    }
    Write-CoreFile (Join-Path $dockerRoot "postgresql\init.sql") $initSql
}

# --- Write .gitignore at the main OutputPath ---
Write-CoreFile (Join-Path $OutputPath ".gitignore") "bin/`nobj/`n*.user`n.vs/`n*.log`n.data/`n*.db`n.env`nnode_modules/`ndist/`n.expo/"