// 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:convert';
import 'dart:io';
import 'dart:math';

import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/socket_server.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'analysis_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 path used to request the list of source files in a certain cache
   * state.
   */
  static const String CACHE_STATE_PATH = '/cache_state';

  /**
   * Query parameter used to represent the cache state to search for, when
   * accessing [CACHE_STATE_PATH].
   */
  static const String STATE_QUERY_PARAM = 'state';

  /**
   * Query parameter used to represent the context to search for, when
   * accessing [CACHE_STATE_PATH].
   */
  static const String CONTEXT_QUERY_PARAM = 'context';

  /**
   * Query parameter used to represent the descriptor to search for, when
   * accessing [CACHE_STATE_PATH].
   */
  static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';

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

  /**
   * Buffer containing strings printed by the analysis server.
   */
  List<String> _printBuffer;

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

  /**
   * 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 if (path == CACHE_STATE_PATH) {
      _returnCacheState(request);
    } else {
      _returnUnknownRequest(request);
    }
  }

  /**
   * Create a link to [path] with query parameters [params], with inner HTML
   * [innerHtml].
   */
  String _makeLink(String path, Map<String, String> params, String innerHtml) {
    Uri uri = new Uri(path: path, queryParameters: params);
    return '<a href="${HTML_ESCAPE.convert(uri.toString())}">$innerHtml</a>';
  }

  /**
   * Return a response indicating the set of source files in a certain cache
   * state.
   */
  void _returnCacheState(HttpRequest request) {
    // Figure out what CacheState is being searched for.
    String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
    if (stateQueryParam == null) {
      return _returnFailure(request,
          'Query parameter $STATE_QUERY_PARAM required');
    }
    CacheState stateFilter = null;
    for (CacheState value in CacheState.values) {
      if (value.toString() == stateQueryParam) {
        stateFilter = value;
      }
    }
    if (stateFilter == null) {
      return _returnFailure(request,
          'Query parameter $STATE_QUERY_PARAM is invalid');
    }

    // Figure out which context is being searched for.
    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
    if (contextFilter == null) {
      return _returnFailure(request,
          'Query parameter $CONTEXT_QUERY_PARAM required');
    }

    // Figure out which descriptor is being searched for.
    String descriptorFilter =
        request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
    if (descriptorFilter == null) {
      return _returnFailure(request,
          'Query parameter $DESCRIPTOR_QUERY_PARAM required');
    }

    AnalysisServer analysisServer = _server.analysisServer;
    if (analysisServer == null) {
      return _returnFailure(request, 'Analysis server not running');
    }
    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 - Search result</title>');
    response.write('</head>');
    response.write('<body>');
    response.write('<h1>');
    response.write('Files with state ${HTML_ESCAPE.convert(stateQueryParam)}');
    response.write(' for descriptor ${HTML_ESCAPE.convert(descriptorFilter)}');
    response.write(' in context ${HTML_ESCAPE.convert(contextFilter)}');
    response.write('</h1>');
    response.write('<ul>');
    int count = 0;
    analysisServer.folderMap.forEach((Folder folder,
                                      AnalysisContextImpl context) {
      if (folder.path != contextFilter) {
        return;
      }
      context.visitCacheItems((Source source, SourceEntry dartEntry,
                               DataDescriptor rowDesc, CacheState state) {
        if (state != stateFilter || rowDesc.toString() != descriptorFilter) {
          return;
        }
        response.write('<li>${HTML_ESCAPE.convert(source.fullName)}</li>');
        count++;
      });
    });
    response.write('</ul>');
    response.write('<p>$count files found</p>');
    response.write('</body>');
    response.write('</html>');
    response.close();
  }

  /**
   * 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('<style>');
    response.write('td.right {text-align: right;}');
    response.write('</style>');
    response.write('</head>');
    response.write('<body>');
    response.write('<h1>Analysis Server</h1>');
    AnalysisServer analysisServer = _server.analysisServer;
    if (analysisServer == null) {
      response.write('<p>Not running</p>');
    } else {
      if (analysisServer.statusAnalyzing) {
        response.write('<p>Running (analyzing)</p>');
      } else {
        response.write('<p>Running (not analyzing)</p>');
      }
      response.write('<h1>Analysis Contexts</h1>');
      response.write('<h2>Summary</h2>');
      response.write('<table>');
      List headerRowText = ['Context'];
      headerRowText.addAll(CacheState.values);
      _writeRow(response, headerRowText, header: true);
      Map<Folder, AnalysisContext> folderMap = analysisServer.folderMap;
      List<Folder> folders = folderMap.keys.toList();
      folders.sort((Folder first, Folder second)
          => first.shortName.compareTo(second.shortName));
      folders.forEach((Folder folder) {
        AnalysisContextImpl context = folderMap[folder];
        String key = folder.shortName;
        AnalysisContextStatistics statistics = context.statistics;
        Map<CacheState, int> totals = <CacheState, int>{};
        for (CacheState state in CacheState.values) {
          totals[state] = 0;
        }
        statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
          for (CacheState state in CacheState.values) {
            totals[state] += row.getCount(state);
          }
        });
        List rowText = ['<a href="#context_${HTML_ESCAPE.convert(key)}">$key</a>'];
        for (CacheState state in CacheState.values) {
          rowText.add(totals[state]);
        }
        _writeRow(response, rowText, classes: [null, "right"]);
      });
      response.write('</table>');
      folders.forEach((Folder folder) {
        AnalysisContextImpl context = folderMap[folder];
        String key = folder.shortName;
        response.write('<h2><a name="context_${HTML_ESCAPE.convert(key)}">Analysis Context: $key</a></h2>');
        AnalysisContextStatistics statistics = context.statistics;
        response.write('<table>');
        _writeRow(response, headerRowText, header: true);
        statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
          List rowText = [row.name];
          for (CacheState state in CacheState.values) {
            String text = row.getCount(state).toString();
            Map<String, String> params = <String, String>{
              STATE_QUERY_PARAM: state.toString(),
              CONTEXT_QUERY_PARAM: folder.path,
              DESCRIPTOR_QUERY_PARAM: row.name
            };
            rowText.add(_makeLink(CACHE_STATE_PATH, params, text));
          }
          _writeRow(response, rowText, classes: [null, "right"]);
        });
        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('<h1>Most recent strings printed by analysis server</h2>');
    response.write('<pre>');
    response.write(HTML_ESCAPE.convert(_printBuffer.join('\n')));
    response.write('</pre>');
    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();
  }

  void _returnFailure(HttpRequest request, String message) {
    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 - Failure</title>');
    response.write('</head>');
    response.write('<body>');
    response.write(HTML_ESCAPE.convert(message));
    response.write('</body>');
    response.write('</html>');
    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, List<String> classes}) {
    response.write('<tr>');
    int count = columns.length;
    int maxClassIndex = classes == null ? 0 : classes.length - 1;
    for (int i = 0; i < count; i++) {
      String classAttribute = '';
      if (classes != null) {
        String className = classes[min(i, maxClassIndex)];
        if (className != null) {
          classAttribute = ' class="$className"';
        }
      }
      if (header) {
        response.write('<th$classAttribute>');
      } else {
        response.write('<td$classAttribute>');
      }
      response.write(columns[i]);
      if (header) {
        response.write('</th>');
      } else {
        response.write('</td>');
      }
    };
    response.write('</tr>');
  }
}