@TestOn('vm')
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:tar/tar.dart' as tar;
import 'package:test/test.dart';

import 'system_tar.dart';

const oneMbSize = 1024 * 1024;
const tenGbSize = oneMbSize * 1024 * 10;

void main() {
  group('writes long file names', () {
    for (final style in tar.OutputFormat.values) {
      test(style.toString(), () async {
        final name = '${'very' * 30} long name.txt';
        final withLongName = tar.TarEntry.data(
          tar.TarHeader(name: name, mode: 0, size: 0),
          Uint8List(0),
        );

        final proc = await writeToTar(['--list'], Stream.value(withLongName),
            format: style);
        expect(proc.lines, emits(contains(name)));
      });
    }
  }, testOn: '!windows');

  test('writes headers', () async {
    final date = DateTime.parse('2020-12-30 12:34');
    final entry = tar.TarEntry.data(
      tar.TarHeader(
        name: 'hello_dart.txt',
        mode: int.parse('744', radix: 8),
        size: 0,
        userId: 3,
        groupId: 4,
        userName: 'my_user',
        groupName: 'long group that exceeds 32 characters',
        modified: date,
      ),
      Uint8List(0),
    );

    final proc = await writeToTar(['--list', '--verbose'], Stream.value(entry));
    expect(
      proc.lines,
      emits(
        allOf(
          contains('-rwxr--r--'),
          contains('my_user'),
          contains('long group that exceeds 32 characters'),
          // The date format is different across GNU and BSD tar
          anyOf(contains('12:34'), contains('Dec 30')),
        ),
      ),
    );
  }, testOn: '!windows');

  test('writes entries synchronously', () async {
    final date = DateTime.parse('2020-12-30 12:34');
    final builder = BytesBuilder(copy: false);
    final sink = tar.tarConverter
        .startChunkedConversion(ByteConversionSink.withCallback(builder.add));

    sink.add(tar.TarEntry.data(
      tar.TarHeader(
        name: 'first.txt',
        mode: int.parse('644', radix: 8),
        size: 0,
        userId: 3,
        groupId: 4,
        userName: 'my_user',
        modified: date,
      ),
      Uint8List(10),
    ));
    sink.add(tar.TarEntry.data(
      tar.TarHeader(
        name: 'second.txt',
        mode: int.parse('644', radix: 8),
        size: 0,
        userId: 3,
        groupId: 4,
        userName: 'my_user',
        modified: date,
      ),
      Uint8List(512),
    ));

    sink.close();

    final process = await startTar(['--list', '--verbose']);
    process.stdin.add(builder.takeBytes());

    expect(
      process.lines,
      emitsInOrder(
        <Matcher>[
          allOf(
            contains('-rw-r--r--'),
            contains('my_user'),
            contains('10'),
            // The date format is different across GNU and BSD tar
            anyOf(contains('12:34'), contains('Dec 30')),
            contains('first.txt'),
          ),
          allOf(
            contains('-rw-r--r--'),
            contains('my_user'),
            contains('512'),
            // The date format is different across GNU and BSD tar
            anyOf(contains('12:34'), contains('Dec 30')),
            contains('second.txt'),
          ),
        ],
      ),
    );

    await process.stdin.close();
  }, testOn: '!windows');

  test('writes huge files', () async {
    final oneMb = Uint8List(oneMbSize);
    const count = tenGbSize ~/ oneMbSize;

    final entry = tar.TarEntry(
      tar.TarHeader(
        name: 'file.blob',
        mode: 0,
        size: tenGbSize,
      ),
      Stream<List<int>>.fromIterable(Iterable.generate(count, (i) => oneMb)),
    );

    final proc = await writeToTar(['--list', '--verbose'], Stream.value(entry));
    expect(proc.lines, emits(contains(tenGbSize.toString())));
  }, testOn: '!windows && !node');

  group('refuses to write files with OutputFormat.gnu', () {
    void shouldThrow(tar.TarEntry entry) {
      final output = tar.tarWritingSink(_NullStreamSink(),
          format: tar.OutputFormat.gnuLongName);
      expect(Stream.value(entry).pipe(output), throwsA(isUnsupportedError));
    }

    test('when they are too large', () {
      final oneMb = Uint8List(oneMbSize);
      const count = tenGbSize ~/ oneMbSize;

      final entry = tar.TarEntry(
        tar.TarHeader(
          name: 'file.blob',
          mode: 0,
          size: tenGbSize,
        ),
        Stream<List<int>>.fromIterable(Iterable.generate(count, (i) => oneMb)),
      );
      shouldThrow(entry);
    });

    test('when they use long user names', () {
      shouldThrow(
        tar.TarEntry.data(
          tar.TarHeader(
            name: 'file.txt',
            userName: 'this name is longer than 32 chars, which is not allowed',
          ),
          [],
        ),
      );
    });
  });
}

class _NullStreamSink<T> extends StreamSink<T> {
  @override
  void add(T event) {}

  @override
  void addError(Object error, [StackTrace? stackTrace]) {
    // ignore: only_throw_errors
    throw error;
  }

  @override
  Future<void> addStream(Stream<T> stream) {
    return stream.forEach(add);
  }

  @override
  Future<void> close() async {}

  @override
  Future<void> get done => close();
}
