// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// This is a manual test that can be run to test the .tar.gz decoding.
/// It will save progress in `statusFileName` such that it doesn't have to be
/// finished in a single run.
library;

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

import 'package:http/http.dart' as http;
import 'package:pool/pool.dart';
import 'package:pub/src/http.dart';
import 'package:pub/src/io.dart';
import 'package:pub/src/log.dart' as log;

const statusFilename = 'extract_all_pub_status.json';

Future<List<String>> allPackageNames() async {
  final nextUrl = Uri.https('pub.dev', 'api/packages', {'compact': '1'});
  final request = http.Request('GET', nextUrl);
  request.attachMetadataHeaders();
  final response = await globalHttpClient.fetch(request);
  final result = json.decode(response.body);
  return List<String>.from((result as Map)['packages'] as List);
}

Future<List<String>> versionArchiveUrls(String packageName) async {
  final url = Uri.https('pub.dev', 'api/packages/$packageName');
  final request = http.Request('GET', url);
  request.attachMetadataHeaders();
  final response = await globalHttpClient.fetch(request);
  final result = json.decode(response.body) as Map;
  return (result['versions'] as List)
      .map((v) => (v as Map)['archive_url'] as String)
      .toList();
}

Future<void> main() async {
  final alreadyDonePackages = <String>{};
  final failures = <Map<String, dynamic>?>[];
  if (fileExists(statusFilename)) {
    final json = jsonDecode(readTextFile(statusFilename)) as Map;
    for (final packageName in json['packages'] as Iterable? ?? []) {
      alreadyDonePackages.add(packageName as String);
    }
    for (final failure
        in (json['failures'] ?? <Map<String, dynamic>>[]) as Iterable) {
      failures.add(failure as Map<String, dynamic>);
    }
  }
  log.message('Already processed ${alreadyDonePackages.length} packages');
  log.message('Already found ${alreadyDonePackages.length}');

  void writeStatus() {
    writeTextFile(
      statusFilename,
      const JsonEncoder.withIndent('  ').convert({
        'packages': [...alreadyDonePackages],
        'failures': [...failures],
      }),
    );
    log.message('Wrote status to $statusFilename');
  }

  ProcessSignal.sigint.watch().listen((_) {
    writeStatus();
    exit(1);
  });

  final pool = Pool(10); // Process 10 packages at a time.

  try {
    for (final packageName in await allPackageNames()) {
      if (alreadyDonePackages.contains(packageName)) {
        log.message('Skipping $packageName - already done');
        continue;
      }
      log.message('Processing all versions of $packageName '
          '[+${alreadyDonePackages.length}, - ${failures.length}]');
      final resource = await pool.request();
      scheduleMicrotask(() async {
        try {
          final versions = await versionArchiveUrls(packageName);
          var allVersionsGood = true;
          await Future.wait(
            versions.map((archiveUrl) async {
              await withTempDir((tempDir) async {
                log.message('downloading $archiveUrl');
                http.StreamedResponse response;
                try {
                  final archiveUri = Uri.parse(archiveUrl);
                  final request = http.Request('GET', archiveUri);
                  request.attachMetadataHeaders();
                  response = await globalHttpClient.fetchAsStream(request);
                  await extractTarGz(response.stream, tempDir);
                  log.message('Extracted $archiveUrl');
                } catch (e) {
                  log.message('Failed to get and extract $archiveUrl $e');
                  failures.add({'archive': archiveUrl, 'error': e.toString()});
                  allVersionsGood = false;
                  return;
                }
              });
            }),
          );
          if (allVersionsGood) alreadyDonePackages.add(packageName);
        } finally {
          resource.release();
        }
      });
    }
  } finally {
    writeStatus();
    exit(failures.isEmpty ? 0 : 1);
  }
}
