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

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, includeParentEnvironment: false)
      .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());
  }
}
