// Wrapper around the `tar` command, for testing.

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

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

Future<Process> startTar(List<String> args, {String? baseDir}) {
  return Process.start('tar', args, workingDirectory: baseDir).then((proc) {
    expect(proc.exitCode, completion(0),
        reason: 'tar ${args.join(' ')} should complete normally');

    // Attach stderr listener, we don't expect any output on that
    late List<int> data;
    final sink = ByteConversionSink.withCallback((result) => data = result);
    proc.stderr.forEach(sink.add).then((Object? _) {
      sink.close();
      const LineSplitter().convert(utf8.decode(data)).forEach(print);
    });

    return proc;
  });
}

Stream<List<int>> createTarStream(Iterable<String> files,
    {String archiveFormat = 'gnu',
    String? sparseVersion,
    String? baseDir}) async* {
  final args = [
    '--format=$archiveFormat',
    '--create',
    ...files,
  ];

  if (sparseVersion != null) {
    args
      ..add('--sparse')
      ..add('--sparse-version=$sparseVersion');
  }

  final tar = await startTar(args, baseDir: baseDir);
  yield* tar.stdout;
}

Future<Process> writeToTar(List<String> args, Stream<tar.TarEntry> entries,
    {tar.OutputFormat format = tar.OutputFormat.pax}) async {
  final proc = await startTar(args);
  await entries.pipe(tar.tarWritingSink(proc.stdin, format: format));

  return proc;
}

extension ProcessUtils on Process {
  Stream<String> get lines {
    return this.stdout.transform(utf8.decoder).transform(const LineSplitter());
  }
}
