// 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:analysis_tool/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>[];
      if (request.params != null) {
        for (var field in request.params.fields) {
          arguments.add('${javaType(field.type)} ${javaName(field.name)}');
        }
      }
      if (request.result != null) {
        arguments.add('${consumerName(request)} consumer');
      }
      write(arguments.join(', '));
      writeln(');');
    });
  }
}
