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

/// Tests Export Json behavior for the Scheduler Export Json package.
library;

import 'dart:convert';
import 'dart:io';

import 'package:scheduler_core/scheduler_core.dart' as core;
import 'package:scheduler_export/export.dart';
import 'package:scheduler_export_json/export_json.dart';
import 'package:scheduler_persistence_memory/persistence_memory.dart';
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('readable registry exports valid JSON through ExportController',
      () async {
    final ownerId = core.OwnerId('owner-a');
    final repository = InMemoryTaskRepository();
    await repository.insert(ownerId: ownerId, task: _task('task-a'));
    final output = StringBuffer();

    await ExportController(
      taskRepository: repository,
      writerRegistry: readableExportWriterRegistry(),
    ).exportTasksToSink(
      context: ExportContext(ownerId: ownerId, timezone: 'UTC', version: 1),
      format: 'json',
      sink: output,
    );

    final decoded = jsonDecode(output.toString()) as Map<String, Object?>;
    expect(decoded['context'], isA<Map<String, Object?>>());
    final tasks = decoded['tasks'] as List<Object?>;
    expect(tasks, hasLength(1));
    expect((tasks.single as Map<String, Object?>)['_id'], 'task-a');
  });

  test('CSV writer quotes cells with commas and quotes', () async {
    final ownerId = core.OwnerId('owner-a');
    final repository = InMemoryTaskRepository();
    await repository.insert(
      ownerId: ownerId,
      task: _task('task-a', title: 'Task, "quoted"'),
    );
    final output = StringBuffer();

    await ExportController(
      taskRepository: repository,
      writerRegistry: readableExportWriterRegistry(),
    ).exportTasksToSink(
      context: ExportContext(ownerId: ownerId, timezone: 'UTC', version: 1),
      format: 'csv',
      sink: output,
    );

    expect(output.toString(), contains('"Task, ""quoted"""'));
  });

  test('export command --json outputs valid JSON', () async {
    final result = await Process.run(
      Platform.resolvedExecutable,
      <String>['run', 'bin/export.dart', '--json'],
      workingDirectory: _packageDirectory().path,
    );

    expect(result.exitCode, 0, reason: result.stderr as String?);
    final decoded = jsonDecode(result.stdout as String) as Map<String, Object?>;
    expect(decoded['tasks'], isA<List<Object?>>());
  }, timeout: const Timeout(Duration(seconds: 20)));
}

/// Top-level helper that performs the `_packageDirectory` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
Directory _packageDirectory() {
  final currentPubspec =
      File('${Directory.current.path}${Platform.pathSeparator}pubspec.yaml');
  if (currentPubspec.existsSync() &&
      currentPubspec
          .readAsStringSync()
          .contains('name: scheduler_export_json')) {
    return Directory.current;
  }
  return Directory(
    '${Directory.current.path}${Platform.pathSeparator}packages'
    '${Platform.pathSeparator}scheduler_export_json',
  );
}

/// Top-level helper that performs the `_task` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
core.Task _task(String id, {String? title}) {
  return core.Task(
    id: id,
    title: title ?? 'Task $id',
    projectId: 'project-a',
    type: core.TaskType.flexible,
    status: core.TaskStatus.backlog,
    durationMinutes: 30,
    createdAt: DateTime.utc(2026, 1),
    updatedAt: DateTime.utc(2026, 1),
  );
}
