// 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',
  (pkgRoot) async {
    var visitor = _CodegenVisitor(readApi(pkgRoot));
    return visitor.collectCode(visitor.visitApi);
  },
);

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

final _upperCaseLettersPattern = RegExp('[A-Z]');

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

/// Returns a name generated by converting each of the given [components] to an
/// uppercase equivalent, then joining them with underscores.
String _fromComponents(List<String> components) {
  var joinedName = components
      .map((s) => '${s[0].toUpperCase()}${s.substring(1)}')
      .join();
  return '${joinedName[0].toLowerCase()}${joinedName.substring(1)}';
}

/// Returns the components of the given String that are indicated by an upper
/// case letter.
Iterable<String> _split(String first) {
  var components = <String>[];
  var start = 1;
  var index = first.indexOf(_upperCaseLettersPattern, start);
  while (index >= 0) {
    components.add(first.substring(start - 1, index));
    start = index + 1;
    index = first.indexOf(_upperCaseLettersPattern, 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 {
  new(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('// ignore: constant_identifier_names');
    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.
  new(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].
  new(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 fieldConstantName = _fromComponents([parentName, ..._split(name)]);
      constants.add(_Constant(fieldConstantName, "'$name'"));
    }
  }
}
