package storage

import (
    "strings"
    "testing"
)

func TestAssetsRepoStoresTemplateProfileAndOverlayJSON(t *testing.T) {
    store := openTestStore(t)
    defer store.Close()

    repo := NewAssetsRepo(store.DB())
    if err := repo.SaveTemplate("helmet", "helmet template", `{"name":"helmet","template":{"nodes":[],"edges":[]}}`); err != nil {
        t.Fatalf("SaveTemplate: %v", err)
    }
    if err := repo.SaveProfile("gate_a", "helmet", "gate", "gate profile", `{"name":"gate_a","instances":[{"name":"cam1","template":"helmet","params":{"display_name":"Gate A"}}]}`); err != nil {
        t.Fatalf("SaveProfile: %v", err)
    }
    if err := repo.SaveOverlay("night_relaxed", "overlay", `{"name":"night_relaxed","instance_overrides":{"cam1":{"override":{}}}}`); err != nil {
        t.Fatalf("SaveOverlay: %v", err)
    }

    templates, err := repo.ListTemplates()
    if err != nil {
        t.Fatalf("ListTemplates: %v", err)
    }
    profiles, err := repo.ListProfiles()
    if err != nil {
        t.Fatalf("ListProfiles: %v", err)
    }
    overlays, err := repo.ListOverlays()
    if err != nil {
        t.Fatalf("ListOverlays: %v", err)
    }
    if len(templates) != 1 || templates[0].Name != "helmet" {
        t.Fatalf("unexpected templates: %#v", templates)
    }
    if len(profiles) != 1 || profiles[0].Name != "gate_a" || profiles[0].TemplateName != "helmet" {
        t.Fatalf("unexpected profiles: %#v", profiles)
    }
    if len(overlays) != 1 || overlays[0].Name != "night_relaxed" {
        t.Fatalf("unexpected overlays: %#v", overlays)
    }
}

func TestAssetsRepoRenameTemplateUpdatesProfileReferences(t *testing.T) {
    store := openTestStore(t)
    defer store.Close()

    repo := NewAssetsRepo(store.DB())
    if err := repo.SaveTemplate("helmet", "helmet template", `{"name":"helmet","description":"helmet template","template":{"nodes":[],"edges":[]}}`); err != nil {
        t.Fatalf("SaveTemplate: %v", err)
    }
    if err := repo.SaveProfile("gate_a", "helmet", "gate", "gate profile", `{"name":"gate_a","business_name":"gate","instances":[{"name":"cam1","template":"helmet","params":{"display_name":"Gate A","rtsp_url":"rtsp://10.0.0.1/live"}}]}`); err != nil {
        t.Fatalf("SaveProfile: %v", err)
    }

    err := repo.RenameTemplate("helmet", "helmet_v2", "helmet v2", `{"name":"helmet_v2","description":"helmet v2","template":{"nodes":[],"edges":[]}}`)
    if err != nil {
        t.Fatalf("RenameTemplate: %v", err)
    }

    oldRecord, err := repo.GetTemplate("helmet")
    if err != nil {
        t.Fatalf("GetTemplate old: %v", err)
    }
    if oldRecord != nil {
        t.Fatalf("expected old template to be removed, got %#v", oldRecord)
    }
    newRecord, err := repo.GetTemplate("helmet_v2")
    if err != nil {
        t.Fatalf("GetTemplate new: %v", err)
    }
    if newRecord == nil || newRecord.Description != "helmet v2" || !strings.Contains(newRecord.BodyJSON, `"name":"helmet_v2"`) {
        t.Fatalf("expected renamed template, got %#v", newRecord)
    }
    profile, err := repo.GetProfile("gate_a")
    if err != nil {
        t.Fatalf("GetProfile: %v", err)
    }
    if profile == nil || profile.TemplateName != "helmet_v2" || !strings.Contains(profile.BodyJSON, `"primary_template_name": "helmet_v2"`) && !strings.Contains(profile.BodyJSON, `"primary_template_name":"helmet_v2"`) {
        t.Fatalf("expected profile template ref updated, got %#v", profile)
    }
}

func TestAssetsRepoDeleteTemplateRemovesRecord(t *testing.T) {
    store := openTestStore(t)
    defer store.Close()

    repo := NewAssetsRepo(store.DB())
    if err := repo.SaveTemplate("helmet", "helmet template", `{"name":"helmet","template":{"nodes":[],"edges":[]}}`); err != nil {
        t.Fatalf("SaveTemplate: %v", err)
    }
    if err := repo.DeleteTemplate("helmet"); err != nil {
        t.Fatalf("DeleteTemplate: %v", err)
    }
    record, err := repo.GetTemplate("helmet")
    if err != nil {
        t.Fatalf("GetTemplate: %v", err)
    }
    if record != nil {
        t.Fatalf("expected template deleted, got %#v", record)
    }
}

func TestAssetsRepoStoresIntegrationServiceDisabledState(t *testing.T) {
    store := openTestStore(t)
    defer store.Close()

    repo := NewAssetsRepo(store.DB())
    if err := repo.SaveIntegrationService(
        "minio_primary",
        "object_storage",
        "primary object store",
        false,
        `{"name":"minio_primary","type":"object_storage","provider":"minio","enabled":false}`,
    ); err != nil {
        t.Fatalf("SaveIntegrationService: %v", err)
    }

    records, err := repo.ListIntegrationServices()
    if err != nil {
        t.Fatalf("ListIntegrationServices: %v", err)
    }
    if len(records) != 1 {
        t.Fatalf("expected one integration service, got %#v", records)
    }
    if records[0].ServiceType != "object_storage" || records[0].Enabled {
        t.Fatalf("unexpected integration service record: %#v", records[0])
    }

    record, err := repo.GetIntegrationService("minio_primary")
    if err != nil {
        t.Fatalf("GetIntegrationService: %v", err)
    }
    if record == nil {
        t.Fatal("expected integration service record")
    }
    if record.ServiceType != "object_storage" || record.Enabled {
        t.Fatalf("unexpected integration service fetch: %#v", record)
    }
    if !strings.Contains(record.BodyJSON, `"provider":"minio"`) {
        t.Fatalf("expected body_json payload preserved, got %#v", record)
    }
}

func TestAssetsRepoStoresVideoSource(t *testing.T) {
    store := openTestStore(t)
    defer store.Close()

    repo := NewAssetsRepo(store.DB())
    if err := repo.SaveVideoSource(
        "gate_cam_01",
        "rtsp",
        "东门入口",
        "东门主入口摄像头",
        `{"name":"gate_cam_01","source_type":"rtsp","area":"东门入口","description":"东门主入口摄像头","config":{"url":"rtsp://10.0.0.1/live","resolution":"1080p","frame_size":"1920x1080","fps":"25","video_format":"h264"}}`,
    ); err != nil {
        t.Fatalf("SaveVideoSource: %v", err)
    }

    records, err := repo.ListVideoSources()
    if err != nil {
        t.Fatalf("ListVideoSources: %v", err)
    }
    if len(records) != 1 {
        t.Fatalf("expected one video source, got %#v", records)
    }
    if records[0].SourceType != "rtsp" || records[0].Area != "东门入口" {
        t.Fatalf("unexpected video source record: %#v", records[0])
    }

    record, err := repo.GetVideoSource("gate_cam_01")
    if err != nil {
        t.Fatalf("GetVideoSource: %v", err)
    }
    if record == nil {
        t.Fatal("expected video source record")
    }
    if record.SourceType != "rtsp" || record.Area != "东门入口" {
        t.Fatalf("unexpected video source fetch: %#v", record)
    }
    if !strings.Contains(record.BodyJSON, `"resolution":"1080p"`) {
        t.Fatalf("expected body_json payload preserved, got %#v", record)
    }
}
