// 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('_');

/// Return 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(Api api) : super(api) {
    codeGeneratorSettings.commentLineLength = 79;
    codeGeneratorSettings.docCommentStartMarker = null;
    codeGeneratorSettings.docCommentLineLeader = '/// ';
    codeGeneratorSettings.docCommentEndMarker = null;
    codeGeneratorSettings.languageName = 'dart';
  }

  /// Generate all of the constants associates 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) {
      generateContant(constant);
    }
  }

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

  @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(Api api) : 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;
    }
    type.fields.forEach((TypeObjectField field) {
      var name = field.name;
      var components = <String>[];
      components.add(parentName);
      components.addAll(_split(name));
      var fieldConstantName = _fromComponents(components);
      constants.add(_Constant(fieldConstantName, "'$name'"));
    });
  }
}
