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

/// Code generation for the file "AnalysisServer.java".
import 'package:analyzer_utilities/tools.dart';

import 'api.dart';
import 'codegen_java.dart';

final GeneratedFile target = javaGeneratedFile(
    'tool/spec/generated/java/AnalysisServer.java',
    (Api api) => CodegenAnalysisServer(api));

class CodegenAnalysisServer extends CodegenJavaVisitor {
  CodegenAnalysisServer(Api api) : super(api);

  @override
  void visitApi() {
    outputHeader(javaStyle: true);
    writeln('package com.google.dart.server.generated;');
    writeln();
    writeln('import com.google.dart.server.*;');
    writeln('import org.dartlang.analysis.server.protocol.*;');
    writeln();
    writeln('import java.util.List;');
    writeln('import java.util.Map;');
    writeln();
    writeln('''/**
 * The interface {@code AnalysisServer} defines the behavior of objects that interface to an
 * analysis server.
 *
 * @coverage dart.server
 */''');
    makeClass('public interface AnalysisServer', () {
      //
      // addAnalysisServerListener(..)
      //
      publicMethod('addAnalysisServerListener', () {
        writeln('''/**
 * Add the given listener to the list of listeners that will receive notification when new
 * analysis results become available.
 *
 * @param listener the listener to be added
 */''');
        writeln(
            'public void addAnalysisServerListener(AnalysisServerListener listener);');
      });

      //
      // removeAnalysisServerListener(..)
      //
      publicMethod('removeAnalysisServerListener', () {
        writeln('''/**
 * Remove the given listener from the list of listeners that will receive notification when new
   * analysis results become available.
 *
 * @param listener the listener to be removed
 */''');
        writeln(
            'public void removeAnalysisServerListener(AnalysisServerListener listener);');
      });

      //
      // addRequestListener(..)
      //
      publicMethod('addRequestListener', () {
        writeln('''/**
 * Add the given listener to the list of listeners that will receive notification when
   * requests are made by an analysis server client.
 *
 * @param listener the listener to be added
 */''');
        writeln('public void addRequestListener(RequestListener listener);');
      });

      //
      // removeRequestListener(..)
      //
      publicMethod('removeRequestListener', () {
        writeln('''/**
 * Remove the given listener from the list of listeners that will receive notification when
   * requests are made by an analysis server client.
 *
 * @param listener the listener to be removed
 */''');
        writeln('public void removeRequestListener(RequestListener listener);');
      });

      //
      // addResponseListener(..)
      //
      publicMethod('addResponseListener', () {
        writeln('''/**
 * Add the given listener to the list of listeners that will receive notification when
 * responses are received by an analysis server client.
 *
 * @param listener the listener to be added
 */''');
        writeln('public void addResponseListener(ResponseListener listener);');
      });

      //
      // removeResponseListener(..)
      //
      publicMethod('removeResponseListener', () {
        writeln('''/**
 * Remove the given listener from the list of listeners that will receive notification when
   * responses are received by an analysis server client.
 *
 * @param listener the listener to be removed
 */''');
        writeln(
            'public void removeResponseListener(ResponseListener listener);');
      });

      //
      // addStatusListener(..)
      //
      publicMethod('addStatusListener', () {
        writeln('''/**
 * Add the given listener to the list of listeners that will receive notification when the server
 * is not active
 *
 * @param listener the listener to be added
 */''');
        writeln(
            'public void addStatusListener(AnalysisServerStatusListener listener);');
      });

      //
      // isSocketOpen()
      //
      publicMethod('isSocketOpen', () {
        writeln('''/**
 * Return {@code true} if the socket is open.
 */''');
        writeln('public boolean isSocketOpen();');
      });

      //
      // start(..)
      //
      publicMethod('start', () {
        writeln('''/**
 * Start the analysis server.
 */''');
        writeln('public void start() throws Exception;');
      });
      super.visitApi();
    });
  }

  @override
  void visitRequest(Request request) {
    var methodName = '${request.domainName}_${request.method}';
    publicMethod(methodName, () {
      docComment(toHtmlVisitor.collectHtml(() {
        toHtmlVisitor.write('{@code ${request.longMethod}}');
        toHtmlVisitor.translateHtml(request.html);
        toHtmlVisitor.javadocParams(request.params);
        if (request.deprecated) {
          toHtmlVisitor.p(() => toHtmlVisitor.write('@deprecated'));
        }
      }));
      write('public void $methodName(');
      var arguments = <String>[];

      var params = request.params;
      if (params != null) {
        for (var field in params.fields) {
          arguments.add('${javaType(field.type)} ${javaName(field.name)}');
        }
      }

      if (request.result != null) {
        arguments.add('${consumerName(request)} consumer');
      }

      write(arguments.join(', '));
      writeln(');');
    });
  }
}
