// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

/// Tests Scheduler Db behavior for the Scheduler Persistence Sqlite package.
library;

import 'dart:io';

import 'package:drift/native.dart';
import 'package:scheduler_persistence_sqlite/sqlite.dart';
import 'package:sqlite3/sqlite3.dart' as sqlite;
import 'package:test/test.dart';

/// Entry point for this executable Dart file.
/// It wires the local command, test, or application behavior needed by this repository without exposing additional public API.
void main() {
  test('opens schema version 2 with expected tables', () async {
    final db = SchedulerDb(NativeDatabase.memory());
    addTearDown(db.close);

    expect(db.schemaVersion, 2);

    final rows = await db
        .customSelect(
          "SELECT name FROM sqlite_master "
          "WHERE type = 'table' AND name NOT LIKE 'sqlite_%' "
          'ORDER BY name',
        )
        .get();
    final tableNames = rows.map((row) => row.data['name']).toList();

    expect(
      tableNames,
      containsAll(<String>[
        'application_operations',
        'locked_blocks',
        'locked_overrides',
        'notice_acknowledgements',
        'projects',
        'project_statistics',
        'settings',
        'snapshots',
        'task_activities',
        'tasks',
      ]),
    );
  });

  test('migrates schema version 1 file and preserves existing rows', () async {
    final directory = await Directory.systemTemp.createTemp(
      'focus-flow-sqlite-migration-',
    );
    addTearDown(() => directory.delete(recursive: true));
    final file = File('${directory.path}/scheduler.sqlite');
    _createVersionOneDatabase(file);

    final db = SchedulerDb(NativeDatabase(file));
    addTearDown(db.close);

    final rows = await db
        .customSelect(
          "SELECT name FROM sqlite_master "
          "WHERE type = 'table' AND name NOT LIKE 'sqlite_%' "
          'ORDER BY name',
        )
        .get();
    final tableNames = rows.map((row) => row.data['name']).toList();
    expect(tableNames, contains('application_operations'));
    expect(tableNames, contains('task_activities'));
    expect(tableNames, contains('project_statistics'));
    expect(tableNames, contains('notice_acknowledgements'));

    final taskRows = await db
        .customSelect("SELECT title FROM tasks WHERE id = 'v1-task'")
        .get();
    final projectRows = await db
        .customSelect("SELECT name FROM projects WHERE id = 'home'")
        .get();
    final settingsRows = await db
        .customSelect(
            "SELECT timezone_id FROM settings WHERE owner_id = 'owner-1'")
        .get();

    expect(taskRows.single.data['title'], 'Existing V1 task');
    expect(projectRows.single.data['name'], 'Home');
    expect(settingsRows.single.data['timezone_id'], 'UTC');
  });
}

/// Creates a minimal version-1 SQLite database file.
void _createVersionOneDatabase(File file) {
  final database = sqlite.sqlite3.open(file.path);
  try {
    database
      ..execute('''
        CREATE TABLE tasks (
          id TEXT PRIMARY KEY NOT NULL,
          owner_id TEXT NOT NULL,
          title TEXT NOT NULL,
          project_id TEXT NOT NULL,
          parent_id TEXT NULL,
          type TEXT NOT NULL,
          status TEXT NOT NULL,
          priority TEXT NULL,
          reward TEXT NOT NULL,
          difficulty TEXT NOT NULL,
          duration_minutes INTEGER NULL,
          scheduled_start_utc INTEGER NULL,
          scheduled_end_utc INTEGER NULL,
          actual_start_utc INTEGER NULL,
          actual_end_utc INTEGER NULL,
          completed_at_utc INTEGER NULL,
          backlog_tags_json TEXT NOT NULL,
          reminder_override TEXT NULL,
          stats_json TEXT NOT NULL,
          backlog_entered_at_utc INTEGER NULL,
          backlog_entered_provenance TEXT NULL,
          revision INTEGER NOT NULL,
          created_at_utc INTEGER NOT NULL,
          updated_at_utc INTEGER NOT NULL
        )
      ''')
      ..execute('''
        CREATE TABLE projects (
          id TEXT PRIMARY KEY NOT NULL,
          owner_id TEXT NOT NULL,
          name TEXT NOT NULL,
          color_key TEXT NOT NULL,
          default_priority TEXT NOT NULL,
          default_reward TEXT NOT NULL,
          default_difficulty TEXT NOT NULL,
          default_reminder_profile TEXT NOT NULL,
          default_duration_minutes INTEGER NULL,
          archived_at_utc INTEGER NULL,
          revision INTEGER NOT NULL,
          created_at_utc INTEGER NOT NULL,
          updated_at_utc INTEGER NOT NULL
        )
      ''')
      ..execute('''
        CREATE TABLE settings (
          owner_id TEXT PRIMARY KEY NOT NULL,
          timezone_id TEXT NOT NULL,
          day_start_minutes INTEGER NOT NULL,
          day_end_minutes INTEGER NOT NULL,
          compact_mode INTEGER NOT NULL,
          backlog_staleness_json TEXT NOT NULL,
          revision INTEGER NOT NULL,
          created_at_utc INTEGER NOT NULL,
          updated_at_utc INTEGER NOT NULL
        )
      ''')
      ..execute('''
        INSERT INTO tasks (
          id,
          owner_id,
          title,
          project_id,
          type,
          status,
          reward,
          difficulty,
          backlog_tags_json,
          stats_json,
          revision,
          created_at_utc,
          updated_at_utc
        ) VALUES (
          'v1-task',
          'owner-1',
          'Existing V1 task',
          'home',
          'flexible',
          'backlog',
          'notSet',
          'notSet',
          '[]',
          '{}',
          1,
          0,
          0
        )
      ''')
      ..execute('''
        INSERT INTO projects (
          id,
          owner_id,
          name,
          color_key,
          default_priority,
          default_reward,
          default_difficulty,
          default_reminder_profile,
          revision,
          created_at_utc,
          updated_at_utc
        ) VALUES (
          'home',
          'owner-1',
          'Home',
          'project-home',
          'medium',
          'notSet',
          'notSet',
          'none',
          1,
          0,
          0
        )
      ''')
      ..execute('''
        INSERT INTO settings (
          owner_id,
          timezone_id,
          day_start_minutes,
          day_end_minutes,
          compact_mode,
          backlog_staleness_json,
          revision,
          created_at_utc,
          updated_at_utc
        ) VALUES (
          'owner-1',
          'UTC',
          0,
          1440,
          1,
          '{}',
          1,
          0,
          0
        )
      ''')
      ..execute('PRAGMA user_version = 1');
  } finally {
    database.close();
  }
}
