// Copyright (c) 2021, 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.

// @dart = 2.9

import 'dart:io';

import 'ast_model.dart';
import 'visitor_generator.dart';

Uri computeCoverageUri(Uri repoDir) {
  return repoDir.resolve('pkg/kernel/lib/src/coverage.dart');
}

void main(List<String> args) async {
  Uri output = args.isEmpty
      ? computeCoverageUri(Uri.base)
      : new File(args[0]).absolute.uri;
  String result = await generateAstCoverage(Uri.base);
  new File.fromUri(output).writeAsStringSync(result);
}

Future<String> generateAstCoverage(Uri repoDir, [AstModel astModel]) async {
  astModel ??= await deriveAstModel(repoDir);
  return generateVisitor(astModel, new CoverageVisitorStrategy());
}

class CoverageVisitorStrategy extends Visitor0Strategy {
  Map<String, Set<String>> nestedClassNames = {};

  @override
  String get generatorCommand =>
      'dart pkg/front_end/tool/generate_ast_coverage.dart';

  @override
  String get returnType => 'void';

  @override
  String get visitorName => 'CoverageVisitor';

  @override
  String get visitorComment => '''
/// Recursive visitor that collects kinds for all visited nodes.
///
/// This can be used to verify that tests have the intended coverage.''';

  @override
  void handleVisit(AstModel astModel, AstClass astClass, StringBuffer sb) {
    AstClass superAstClass = astClass.superclass;
    while (superAstClass != null && !superAstClass.isInterchangeable) {
      superAstClass = superAstClass.superclass;
    }
    String innerName = superAstClass?.name ?? 'Node';
    (nestedClassNames[innerName] ??= {}).add(astClass.name);
    sb.writeln('''
    visited.add(${innerName}Kind.${astClass.name});
    node.visitChildren(this);''');
  }

  @override
  void handleVisitReference(
      AstModel astModel, AstClass astClass, StringBuffer sb) {
    AstClass superAstClass = astClass.superclass;
    while (superAstClass != null && !superAstClass.isInterchangeable) {
      superAstClass = superAstClass.superclass;
    }
    if (superAstClass == astModel.constantClass) {
      // Constants are only visited as references.
      String innerName = superAstClass.name;
      (nestedClassNames[innerName] ??= {}).add(astClass.name);
      sb.writeln('''
        visited.add(${innerName}Kind.${astClass.name});
        node.visitChildren(this);''');
    }
  }

  @override
  void generateHeader(AstModel astModel, StringBuffer sb) {
    super.generateHeader(astModel, sb);
    sb.writeln('''
    Set<Object> visited = {};''');
  }

  @override
  void generateFooter(AstModel astModel, StringBuffer sb) {
    super.generateFooter(astModel, sb);
    nestedClassNames.forEach((String innerName, Set<String> classNames) {
      sb.writeln('''

enum ${innerName}Kind {''');
      for (String className in classNames.toList()..sort()) {
        sb.writeln('''
  $className,''');
      }
      sb.writeln('''
}''');
    });
    sb.writeln('''

/// Returns the set of node kinds that were not visited by [visitor].
Set<Object> missingNodes($visitorName visitor) {
  Set<Object> all = {''');
    nestedClassNames.forEach((String innerName, Set<String> classNames) {
      sb.writeln('''
    ...${innerName}Kind.values,''');
    });
    sb.writeln('''
  };
  all.removeAll(visitor.visited);
  return all;
}''');
    nestedClassNames.forEach((String innerName, Set<String> classNames) {
      if (innerName == 'Node') return;
      sb.writeln('''
/// Returns the set of [${innerName}Kind]s that were not visited by [visitor].
Set<${innerName}Kind> missing${innerName}s($visitorName visitor) {
  Set<${innerName}Kind> all = 
    new Set<${innerName}Kind>.from(${innerName}Kind.values);
  all.removeAll(visitor.visited);
  return all;
}''');
    });
  }
}
