import 'dart:async';
import 'dart:io';

import 'package:flutter_test/flutter_test.dart';

import 'package:chanora_flutter/services/app_bootstrap.dart';

void main() {
  setUp(() {
    debugResetStorageBootstrap();
  });

  tearDown(() {
    debugResetStorageBootstrap();
  });

  test('app version appends platform build number', () {
    expect(
      appVersionFromBuildNumber(
        semverBaseline: 'v1.2.3-rc.4',
        buildNumber: '56',
      ),
      'v1.2.3-rc.4+56',
    );
  });

  test('app version keeps baseline when build number is empty', () {
    expect(
      appVersionFromBuildNumber(semverBaseline: 'v1.2.3-rc.4', buildNumber: ''),
      'v1.2.3-rc.4',
    );
  });

  test('wireStorage reuses the in-flight initialization future', () async {
    final completer = Completer<void>();
    final tempDir = await Directory.systemTemp.createTemp(
      'chanora-app-bootstrap-test',
    );
    addTearDown(() => tempDir.delete(recursive: true));

    var initCalls = 0;
    debugResetStorageBootstrap(
      storageDirectoryProvider: () async => tempDir,
      storageInitializer: (dir) async {
        initCalls += 1;
        await completer.future;
      },
    );

    final first = wireStorage();
    final second = wireStorage();
    var secondCompleted = false;
    second.then((_) => secondCompleted = true);

    await Future<void>.delayed(Duration.zero);
    expect(initCalls, 1);
    expect(secondCompleted, isFalse);

    completer.complete();
    await Future.wait([first, second]);
    expect(initCalls, 1);
    expect(secondCompleted, isTrue);
  });

  test('wireStorage retries after a failed initialization attempt', () async {
    final tempDir = await Directory.systemTemp.createTemp(
      'chanora-app-bootstrap-test',
    );
    addTearDown(() => tempDir.delete(recursive: true));

    var initCalls = 0;
    debugResetStorageBootstrap(
      storageDirectoryProvider: () async => tempDir,
      storageInitializer: (dir) async {
        initCalls += 1;
        if (initCalls == 1) {
          throw const FileSystemException('boom');
        }
      },
    );

    await wireStorage();
    await wireStorage();

    expect(initCalls, 2);
  });
}
