// Copyright (c) 2023, 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 script generates a test package with a specified number of libraries,
/// classes, methods, and doc comment references, in order to test analyzer's
/// performance, scalability, and stability characteristics.
///
/// Call with `--help` to see all of the args.
library generate_testing_package;

import 'dart:io';
import 'dart:math';

import 'package:args/args.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;

void main(List<String> args) async {
  // TODO(srawlins): Support multiple packages which depend on each other, in a
  // DAG similar to the import graph.
  var argParser = ArgParser()
    ..addOption(
      'library-count',
      defaultsTo: '1',
      help: 'the number of libraries',
    )
    ..addOption(
      'class-count',
      defaultsTo: '1',
      help: 'the number of classes per library',
    )
    ..addOption(
      'method-count',
      defaultsTo: '1',
      help: 'the number of methods per class',
    )
    ..addOption(
      'parameter-count',
      defaultsTo: '1',
      help: 'the number of parameters per method',
    )
    ..addFlag('use-barrel-file', help: 'Whether to add a barrel import')
    ..addFlag('use-json-serializable',
        help: 'Whether to declare @JsonSerializable classes');
  var argResults = argParser.parse(args);
  var libraryCount = int.parse(argResults['library-count'] as String);
  var classCount = int.parse(argResults['class-count'] as String);
  var methodCount = int.parse(argResults['method-count'] as String);
  var parameterCount = int.parse(argResults['parameter-count'] as String);
  var useBarrelFile = argResults['use-barrel-file'] as bool;
  var useJsonSerializable = argResults['use-json-serializable'] as bool;
  var testDataDir = Directory('test_data')..createSync();
  var libFiles = <d.Descriptor>[];
  var classCounter = 1;
  var methodCounter = 1;
  var middleImportIndex = libraryCount ~/ 2;
  // We need a global index for the names of top-level variables, to avoid
  // ambiguous elements from imports.
  var topLevelVariableIndex = 1;
  for (var lIndex = 1; lIndex <= libraryCount; lIndex++) {
    var libraryName = 'lib$lIndex'.padLeft(3, '0');
    // Each library has an index, starting at 1. The libraries depend on each
    // other in tiers. The "tier" of a library is the base-2 logarithm of its
    // index. Libraries in higher tiers depend on libraries in lower tiers.
    // Libraries in higher tiers depend on more libraries than those in lower
    // tiers.
    //
    // In a package with 10 libraries, we have the following tiers and
    // dependencies:
    // * T0: lib1 - no imports
    // * T1: lib2 - imports lib1
    // * T2: lib3, lib4 - each imports two libraries from T0, T1
    // * T3: lib5, lib6, lib7, lib8 - each imports three libraries from T0, T1,
    //       and T2
    // * T4: lib9, lib10 - each imports four libraries from T0, T1, T2, T3
    //
    // In a package with 1000 libraries, there are 11 tiers, and libraries in
    // the last have 10 imports each.
    // TODO(srawlins): Make the "connectedness" of the import graph
    // configurable.
    var importGraphTier = (log(lIndex) / ln2).ceil();
    var importIndexStep =
        importGraphTier == 0 ? -1 : (lIndex - 1) ~/ importGraphTier;
    var content = StringBuffer();
    if (useJsonSerializable) {
      content.writeln("import 'package:json_annotation/json_annotation.dart';");
    }
    // Add imports in a library above tier 0.
    if (importGraphTier > 0) {
      if (useBarrelFile && lIndex > middleImportIndex) {
        content.writeln(import(testPackageLibUri('barrel.dart')));
      }
      for (var tierIndex = 1; tierIndex <= importGraphTier; tierIndex++) {
        var importIndex = tierIndex * importIndexStep;
        if (useBarrelFile) {
          if (lIndex <= middleImportIndex || importIndex > middleImportIndex) {
            content.writeln(import(testPackageLibUri('lib$importIndex.dart')));
          }
        } else {
          content.writeln(import(testPackageLibUri('lib$importIndex.dart')));
        }
      }
      content.writeln();
    }

    if (useJsonSerializable) {
      content.writeln("part '$libraryName.g.dart';");
      content.writeln();
    }

    // Add top-level variables above tier 0.
    if (importGraphTier > 0) {
      for (var tierIndex = 1; tierIndex <= importGraphTier; tierIndex++) {
        var importIndex = tierIndex * importIndexStep;
        // We instantiate a class which is guaranteed to be found in
        // `lib$importIndex.dart`.
        var classReferenceIndex = classCount * importIndex;
        content
            .writeln('var x$topLevelVariableIndex = C$classReferenceIndex();');
        topLevelVariableIndex++;
      }
      content.writeln();
    }

    for (var cIndex = 1; cIndex <= classCount; cIndex++) {
      content.writeln('/// Doc comment.');
      if (useJsonSerializable) {
        content.writeln('@JsonSerializable()');
      }
      content.writeln('class C$classCounter {');
      if (useJsonSerializable) {
        content.writeln('  C$classCounter();');
        content.writeln(
            '  factory C$classCounter.fromJson(Map<String, dynamic> json) => '
            '_\$C${classCounter}FromJson(json);');
        content.writeln('  Map<String, dynamic> toJson() => '
            '_\$C${classCounter}ToJson(this);');
      }
      for (var mIndex = 1; mIndex <= methodCount; mIndex++) {
        content.write('  void m$methodCounter(');
        content.write(List.generate(parameterCount, (pIndex) => 'int p$pIndex')
            .join(', '));
        content.writeln(') {}');
        methodCounter++;
      }
      content.writeln('}');
      classCounter++;
    }
    libFiles.add(d.file('$libraryName.dart', content.toString()));
  }

  if (useBarrelFile) {
    // Write the barrel file, which exports the first half of the libraries.
    var content = StringBuffer();
    for (var j = 1; j <= middleImportIndex; j++) {
      content.writeln(export(testPackageLibUri('lib$j.dart')));
    }
    libFiles.add(d.file('barrel.dart', content.toString()));
  }

  var testPackageDir = d.dir('test_package', [
    d.file('pubspec.yaml', pubspec(useJsonSerializable: useJsonSerializable)),
    d.dir('lib', libFiles),
  ]);
  await testPackageDir.create(testDataDir.path);
}

String export(String uri) => "export '$uri';";

String import(String uri) => "import '$uri';";

/// Returns the text of a 'pubspec.yaml' file.
///
/// With [useJsonSerializable], several packages are added to the dependencies
/// in order to test using build_runner.
String pubspec({required bool useJsonSerializable}) {
  var dependencies = useJsonSerializable
      ? '''
dependencies:
  json_annotation: any
  json_serializable: any
'''
      : '';
  var devDependencies = useJsonSerializable
      ? '''
dev_dependencies:
  build_runner: any
'''
      : '';
  return '''
name: test_package
version: 0.0.1
environment:
  sdk: '>=2.12.0 <3.0.0'
$dependencies
$devDependencies
''';
}

String testPackageLibUri(String path) => 'package:test_package/$path';
