// 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.

import '../config/config.dart';
import '../elements/elements.dart';
import '../logging/logging.dart';
import 'visitor.dart';

extension on ClassMember {
  bool get isPrivate => !isPublic;
}

// TODO(https://github.com/dart-lang/native/issues/1164): Kotlin compiler
// appends the method name with a dash and a hash code when arguments contain
// inline classes. This is because inline classes do not have any runtime type
// and the typical operator overloading supported by JVM cannot work for them.
//
// Once we support inline classes, we can relax the following constraints.
final _validDartIdentifier = RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$');

extension on String {
  bool get isInvalidDartIdentifier =>
      !_validDartIdentifier.hasMatch(this) &&
      this != '<init>' &&
      this != '<clinit>';
}

class Excluder extends Visitor<Classes, void> with TopLevelVisitor {
  @override
  final GenerationStage stage = GenerationStage.excluder;

  final Config config;

  const Excluder(this.config);

  @override
  void visit(Classes node) {
    node.decls.removeWhere((_, classDecl) {
      final excluded = classDecl.isPrivate || classDecl.isExcluded;
      if (excluded) {
        log.fine('Excluded class ${classDecl.binaryName}');
      }
      if (classDecl.name.isInvalidDartIdentifier) {
        log.warning('Excluded class ${classDecl.binaryName}: the name is not a'
            ' valid Dart identifer');
        return true;
      }
      return excluded;
    });
    final classExcluder = _ClassExcluder(config);
    for (final classDecl in node.decls.values) {
      classDecl.accept(classExcluder);
    }
  }
}

class _ClassExcluder extends Visitor<ClassDecl, void> {
  final Config config;

  _ClassExcluder(this.config);

  @override
  void visit(ClassDecl node) {
    node.methods = node.methods.where((method) {
      final isExcluded = method.userDefinedIsExcluded;
      final isPrivate = method.isPrivate;
      final isAbstractCtor = method.isConstructor && node.isAbstract;
      final isBridgeMethod = method.isSynthetic && method.isBridge;
      final excluded =
          isPrivate || isAbstractCtor || isBridgeMethod || isExcluded;
      if (excluded) {
        log.fine('Excluded method ${node.binaryName}#${method.name}');
      }
      if (method.name.isInvalidDartIdentifier) {
        log.warning(
            'Excluded method ${node.binaryName}#${method.name}: the name is not'
            ' a valid Dart identifer');
        return false;
      }
      return !excluded;
    }).toList();
    node.fields = node.fields.where((field) {
      final excluded = field.isExcluded || field.isPrivate;
      if (excluded) {
        log.fine('Excluded field ${node.binaryName}#${field.name}');
      }
      if (field.name.isInvalidDartIdentifier) {
        log.warning(
            'Excluded field ${node.binaryName}#${field.name}: the name is not'
            ' a valid Dart identifer');
        return false;
      }
      return !excluded;
    }).toList();
  }
}
