// Copyright (c) 2017, 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 'package:analyzer_utilities/tools.dart';

import 'api.dart';
import 'codegen_dart.dart';
import 'from_html.dart';

final GeneratedFile clientTarget = GeneratedFile(
  '../analysis_server_client/lib/src/protocol/protocol_constants.dart',
  (String pkgPath) async {
    var visitor = _CodegenVisitor(readApi(pkgPath));
    return visitor.collectCode(visitor.visitApi);
  },
);

final GeneratedFile serverTarget = GeneratedFile(
  'lib/protocol/protocol_constants.dart',
  (String pkgPath) async {
    var visitor = _CodegenVisitor(readApi(pkgPath));
    return visitor.collectCode(visitor.visitApi);
  },
);

/// Generate a name from the [domainName], [kind] and [name] components.
String generateConstName(String domainName, String kind, String name) {
  var components = <String>[];
  components.addAll(_split(domainName));
  components.add(kind);
  components.addAll(_split(name));
  return _fromComponents(components);
}

/// Return a name generated by converting each of the given [components] to an
/// uppercase equivalent, then joining them with underscores.
String _fromComponents(List<String> components) =>
    components.map((String component) => component.toUpperCase()).join('_');

/// Returns the components of the given String that are indicated by an upper
/// case letter.
Iterable<String> _split(String first) {
  var regExp = RegExp('[A-Z]');
  var components = <String>[];
  var start = 1;
  var index = first.indexOf(regExp, start);
  while (index >= 0) {
    components.add(first.substring(start - 1, index));
    start = index + 1;
    index = first.indexOf(regExp, start);
  }
  components.add(first.substring(start - 1));
  return components;
}

/// A visitor that produces Dart code defining constants associated with the
/// API.
class _CodegenVisitor extends DartCodegenVisitor with CodeGenerator {
  _CodegenVisitor(super.api) {
    codeGeneratorSettings.commentLineLength = 79;
    codeGeneratorSettings.docCommentStartMarker = null;
    codeGeneratorSettings.docCommentLineLeader = '/// ';
    codeGeneratorSettings.docCommentEndMarker = null;
    codeGeneratorSettings.languageName = 'dart';
  }

  /// Generate the given [constant].
  void generateConstant(_Constant constant) {
    write('const String ');
    write(constant.name);
    write(' = ');
    write(constant.value);
    writeln(';');
  }

  /// Generate all of the constants associated with the [api].
  void generateConstants() {
    writeln("const String PROTOCOL_VERSION = '${api.version}';");
    writeln();
    var visitor = _ConstantVisitor(api);
    visitor.visitApi();
    var constants = visitor.constants;
    constants.sort((first, second) => first.name.compareTo(second.name));
    for (var constant in constants) {
      generateConstant(constant);
    }
  }

  @override
  void visitApi() {
    outputHeader(year: '2017');
    writeln();
    generateConstants();
  }
}

/// A representation of a constant that is to be generated.
class _Constant {
  /// The name of the constant.
  final String name;

  /// The value of the constant.
  final String value;

  /// Initialize a newly created constant.
  _Constant(this.name, this.value);
}

/// A visitor that visits an API to compute a list of constants to be generated.
class _ConstantVisitor extends HierarchicalApiVisitor {
  /// The list of constants to be generated.
  List<_Constant> constants = <_Constant>[];

  /// Initialize a newly created visitor to visit the given [api].
  _ConstantVisitor(super.api);

  @override
  void visitNotification(Notification notification) {
    var domainName = notification.domainName;
    var event = notification.event;

    var constantName = generateConstName(domainName, 'notification', event);
    constants.add(_Constant(constantName, "'$domainName.$event'"));
    _addFieldConstants(constantName, notification.params);
  }

  @override
  void visitRequest(Request request) {
    var domainName = request.domainName;
    var method = request.method;

    var requestConstantName = generateConstName(domainName, 'request', method);
    constants.add(_Constant(requestConstantName, "'$domainName.$method'"));
    _addFieldConstants(requestConstantName, request.params);

    var responseConstantName = generateConstName(
      domainName,
      'response',
      method,
    );
    _addFieldConstants(responseConstantName, request.result);
  }

  /// Generate a constant for each of the fields in the given [type], where the
  /// name of each constant will be composed from the [parentName] and the name
  /// of the field.
  void _addFieldConstants(String parentName, TypeObject? type) {
    if (type == null) {
      return;
    }
    for (var field in type.fields) {
      var name = field.name;
      var components = <String>[];
      components.add(parentName);
      components.addAll(_split(name));
      var fieldConstantName = _fromComponents(components);
      constants.add(_Constant(fieldConstantName, "'$name'"));
    }
  }
}
