// Package store persists deployment progress and Slice-2 metadata in
// SQLite, and log lines in append-only .log files. The hot path is
// AppendEvent — agents emit a lot of these and the dashboard wants them
// live. Slice 2 adds sandboxes, templates, environments, routes, and
// port allocations on top of the deployment rows.
package store

import (
	"database/sql"
	"os"
	"path/filepath"
	"sync"

	_ "modernc.org/sqlite"
)

type Store struct {
	db   *sql.DB
	dir  string
	logs map[string]*os.File // deploymentID -> file
	mu   sync.Mutex
}

func Open(dir string) (*Store, error) {
	if err := os.MkdirAll(dir, 0o755); err != nil {
		return nil, err
	}
	if err := os.MkdirAll(filepath.Join(dir, "logs"), 0o755); err != nil {
		return nil, err
	}
	db, err := sql.Open("sqlite", filepath.Join(dir, "sdp.db"))
	if err != nil {
		return nil, err
	}
	if _, err := db.Exec(schema); err != nil {
		return nil, err
	}
	return &Store{db: db, dir: dir, logs: make(map[string]*os.File)}, nil
}

const schema = `
CREATE TABLE IF NOT EXISTS deployments (
    id TEXT PRIMARY KEY,
    sandbox_id TEXT,
    repository TEXT,
    branch TEXT,
    user TEXT,
    state TEXT,
    container_id TEXT,
    host_port INTEGER,
    started_at INTEGER,
    completed_at INTEGER
);
CREATE TABLE IF NOT EXISTS progress (
    deployment_id TEXT,
    stage TEXT,
    ok INTEGER,
    at INTEGER
);

CREATE TABLE IF NOT EXISTS sandboxes (
    id TEXT PRIMARY KEY,
    name TEXT UNIQUE NOT NULL,
    gateway_branch TEXT,
    gateway_env_id TEXT,
    gateway_host_port INTEGER,
    created_at INTEGER,
    updated_at INTEGER
);
CREATE TABLE IF NOT EXISTS sandbox_services (
    id TEXT PRIMARY KEY,
    sandbox_id TEXT NOT NULL,
    repo TEXT NOT NULL,
    branch TEXT,
    env_id TEXT,
    host_port INTEGER,
    use_ocp INTEGER DEFAULT 0
);

CREATE TABLE IF NOT EXISTS templates (
    id TEXT PRIMARY KEY,
    name TEXT UNIQUE NOT NULL,
    gateway_branch TEXT,
    created_at INTEGER,
    updated_at INTEGER
);
CREATE TABLE IF NOT EXISTS template_services (
    id TEXT PRIMARY KEY,
    template_id TEXT NOT NULL,
    repo TEXT NOT NULL,
    branch TEXT,
    env_id TEXT,
    host_port INTEGER,
    use_ocp INTEGER DEFAULT 0
);

CREATE TABLE IF NOT EXISTS environments (
    id TEXT PRIMARY KEY,
    name TEXT UNIQUE NOT NULL,
    values_json TEXT NOT NULL,
    created_at INTEGER,
    updated_at INTEGER
);

CREATE TABLE IF NOT EXISTS routes (
    id TEXT PRIMARY KEY,
    sandbox_id TEXT NOT NULL,
    key TEXT NOT NULL,
    value TEXT,
    target_ocp INTEGER NOT NULL DEFAULT 0
);
`

func (s *Store) Close() error {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, f := range s.logs {
		_ = f.Close()
	}
	return s.db.Close()
}
