// 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.

library get.handler;

import 'dart:io';

import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;

import 'package:analysis_server/src/socket_server.dart';

/**
 * Instances of the class [GetHandler] handle GET requests.
 */
class GetHandler {
  /**
   * The path used to request the status of the analysis server as a whole.
   */
  static const String STATUS_PATH = '/status';

  /**
   * The socket server whose status is to be reported on.
   */
  SocketServer _server;

  /**
   * Initialize a newly created handler for GET requests.
   */
  GetHandler(SocketServer this._server);

  /**
   * Handle a GET request received by the HTTP server.
   */
  void handleGetRequest(HttpRequest request) {
    String path = request.uri.path;
    if (path == STATUS_PATH) {
      _returnServerStatus(request);
    } else {
      _returnUnknownRequest(request);
    }
  }

  /**
   * Return a response indicating the status of the analysis server.
   */
  void _returnServerStatus(HttpRequest request) {
    HttpResponse response = request.response;
    response.statusCode = HttpStatus.OK;
    response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
    response.write('<html>');
    response.write('<head>');
    response.write('<title>Dart Analysis Server - Status</title>');
    response.write('</head>');
    response.write('<body>');
    response.write('<h1>Analysis Server</h1>');
    if (_server.analysisServer == null) {
      response.write('<p>Not running</p>');
    } else {
      response.write('<p>Running</p>');
      response.write('<h1>Analysis Contexts</h1>');
      response.write('<h2>Summary</h2>');
      response.write('<table>');
      _writeRow(
          response,
          ['Context', 'ERROR', 'FLUSHED', 'IN_PROCESS', 'INVALID', 'VALID'],
          true);
      _server.analysisServer.contextMap.forEach((String key, AnalysisContext context) {
        AnalysisContextStatistics statistics =
            (context as AnalysisContextImpl).statistics;
        int errorCount = 0;
        int flushedCount = 0;
        int inProcessCount = 0;
        int invalidCount = 0;
        int validCount = 0;
        statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
          errorCount += row.errorCount;
          flushedCount += row.flushedCount;
          inProcessCount += row.inProcessCount;
          invalidCount += row.invalidCount;
          validCount += row.validCount;
        });
        _writeRow(response, [
            '<a href="#context_$key">$key</a>',
            errorCount,
            flushedCount,
            inProcessCount,
            invalidCount,
            validCount]);
      });
      response.write('</table>');
      _server.analysisServer.contextMap.forEach((String key, AnalysisContext context) {
        response.write('<h2><a name="context_$key">Analysis Context: $key</a></h2>');
        AnalysisContextStatistics statistics = (context as AnalysisContextImpl).statistics;
        response.write('<table>');
        _writeRow(
            response,
            ['Item', 'ERROR', 'FLUSHED', 'IN_PROCESS', 'INVALID', 'VALID'],
            true);
        statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
          _writeRow(
              response,
              [row.name,
               row.errorCount,
               row.flushedCount,
               row.inProcessCount,
               row.invalidCount,
               row.validCount]);
        });
        response.write('</table>');
        List<CaughtException> exceptions = statistics.exceptions;
        if (!exceptions.isEmpty) {
          response.write('<h2>Exceptions</h2>');
          exceptions.forEach((CaughtException exception) {
            response.write('<p>${exception.exception}</p>');
          });
        }
      });
    }
    response.write('</body>');
    response.write('</html>');
    response.close();
  }

  /**
   * Return an error in response to an unrecognized request received by the HTTP
   * server.
   */
  void _returnUnknownRequest(HttpRequest request) {
    HttpResponse response = request.response;
    response.statusCode = HttpStatus.NOT_FOUND;
    response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
    response.write('Not found');
    response.close();
  }

  /**
   * Write a single row within a table to the given [response] object. The row
   * will have one cell for each of the [columns], and will be a header row if
   * [header] is `true`.
   */
  void _writeRow(HttpResponse response, List<Object> columns, [bool header = false]) {
    if (header) {
      response.write('<th>');
    } else {
      response.write('<tr>');
    }
    columns.forEach((Object value) {
      response.write('<td>');
      response.write(value);
      response.write('</td>');
    });
    if (header) {
      response.write('</th>');
    } else {
      response.write('</tr>');
    }
  }
}