import 'dart:io';

import 'package:flutter_test/flutter_test.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:pyramid/core/auth_log.dart';

/// Plattform kaputt/nicht verfügbar (z. B. sehr früher App-Start, exotischer
/// Fehler): genau der Fall, in dem AuthLog.write NIEMALS werfen darf – der
/// Soft-Logout-Guard ruft es in seinem catch-Pfad auf, und ein Throw dort
/// würde im SDK zu logout()+clear() eskalieren (der Uta-Bug).
class _BrokenPathProvider extends PathProviderPlatform {
  @override
  Future<String?> getApplicationSupportPath() async =>
      throw StateError('Plattform nicht verfügbar');
}

class _TempPathProvider extends PathProviderPlatform {
  _TempPathProvider(this.path);
  final String path;

  @override
  Future<String?> getApplicationSupportPath() async => path;
}

void main() {
  // WICHTIG: Reihenfolge der Tests ist Absicht. AuthLog cached sein File-Handle
  // statisch; der Kaputt-Plattform-Test muss laufen, BEVOR ein Test mit
  // funktionierender Plattform das Handle in den Cache legt.
  late Directory tempDir;

  setUpAll(() {
    tempDir = Directory.systemTemp.createTempSync('pyramid_auth_log_test');
  });

  tearDownAll(() {
    tempDir.deleteSync(recursive: true);
  });

  test(
      'write/read werfen NIE, auch wenn die Plattform fehlt '
      '(CLAUDE.md: Fehlerpfade dürfen nie in einem stillen Logout enden)',
      () async {
    PathProviderPlatform.instance = _BrokenPathProvider();
    // Darf normal zurückkehren, obwohl getApplicationSupportPath wirft.
    await AuthLog.write('darf nicht werfen');
    expect(await AuthLog.read(), startsWith('Log konnte nicht gelesen werden'));
  });

  test('read ohne bisherige Einträge liefert Platzhalter statt Fehler',
      () async {
    PathProviderPlatform.instance = _TempPathProvider(tempDir.path);
    expect(await AuthLog.read(), '(noch keine Einträge)');
  });

  test('write hängt Zeile mit ISO-Zeitstempel an, read liefert sie zurück',
      () async {
    PathProviderPlatform.instance = _TempPathProvider(tempDir.path);
    await AuthLog.write('Hallo Log');
    final content = await AuthLog.read();
    expect(content, contains('Hallo Log'));
    expect(
      RegExp(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}').hasMatch(content),
      isTrue,
      reason: 'jede Zeile beginnt mit einem ISO-8601-Zeitstempel',
    );
  });

  test(
      'Log wird auf 500 Zeilen gekappt (älteste fliegen raus), '
      'damit es nie unbegrenzt wächst', () async {
    PathProviderPlatform.instance = _TempPathProvider(tempDir.path);
    for (var i = 0; i < 520; i++) {
      await AuthLog.write('Zeile $i');
    }
    final lines = (await AuthLog.read()).trimRight().split('\n');
    expect(lines.length, 500);
    expect(lines.last, contains('Zeile 519'),
        reason: 'neueste Einträge müssen überleben');
    expect((await AuthLog.read()).contains('Hallo Log'), isFalse,
        reason: 'ältester Eintrag (aus dem Test davor) muss weggekappt sein');
  });
}
