// Copyright (c) 2015, 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 services.common_server_impl;

import 'dart:async';
import 'dart:convert';

import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
import 'package:logging/logging.dart';
import 'package:pedantic/pedantic.dart';
import 'package:protobuf/protobuf.dart' as $pb;

import '../version.dart';
import 'analysis_servers.dart';
import 'common.dart';
import 'compiler.dart';
import 'protos/dart_services.pb.dart' as proto;
import 'sdk.dart';
import 'server_cache.dart';

const Duration _standardExpiration = Duration(hours: 1);
final Logger log = Logger('common_server');

class BadRequest implements Exception {
  String cause;

  BadRequest(this.cause);
}

abstract class ServerContainer {
  String get version;
}

class CommonServerImplProxy implements CommonServerImpl {
  const CommonServerImplProxy(this._proxyTarget);
  final String _proxyTarget;
  final bool _nullSafety = false;

  Future<R> _postToProxy<R extends $pb.GeneratedMessage>(
      String url, $pb.GeneratedMessage request, R responseProto) async {
    final proxyResponse = http.post(url,
        headers: {'Content-Type': 'application/json; charset=utf-8'},
        body: _jsonEncoder.convert(request.toProto3Json()));

    return proxyResponse.then((response) async {
      if (response.statusCode == 200) {
        return responseProto
          ..mergeFromProto3Json(JsonDecoder().convert(response.body));
      } else {
        final err = proto.BadRequest.create()
          ..mergeFromProto3Json(JsonDecoder().convert(response.body));
        throw BadRequest(err.error.message);
      }
    });
  }

  @override
  Future<proto.AnalysisResults> analyze(proto.SourceRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/analyze';
    return _postToProxy(url, request, proto.AnalysisResults.create());
  }

  @override
  Future<proto.AssistsResponse> assists(proto.SourceRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/assists';
    return _postToProxy(url, request, proto.AssistsResponse.create());
  }

  @override
  Future<proto.CompileResponse> compile(proto.CompileRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/compile';
    return _postToProxy(url, request, proto.CompileResponse.create());
  }

  @override
  Future<proto.CompileDDCResponse> compileDDC(proto.CompileDDCRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/compileDDC';
    return _postToProxy(url, request, proto.CompileDDCResponse.create());
  }

  @override
  Future<proto.CompleteResponse> complete(proto.SourceRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/complete';
    return _postToProxy(url, request, proto.CompleteResponse.create());
  }

  @override
  Future<proto.DocumentResponse> document(proto.SourceRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/document';
    return _postToProxy(url, request, proto.DocumentResponse.create());
  }

  @override
  Future<proto.FixesResponse> fixes(proto.SourceRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/fixes';
    return _postToProxy(url, request, proto.FixesResponse.create());
  }

  @override
  Future<proto.FormatResponse> format(proto.SourceRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/format';
    return _postToProxy(url, request, proto.FormatResponse.create());
  }

  @override
  Future<proto.VersionResponse> version(proto.VersionRequest request) {
    final url = '${_proxyTarget}api/dartservices/v2/version';
    return _postToProxy(url, request, proto.VersionResponse.create());
  }

  @override
  Future<String> _checkCache(String query) => null;

  @override
  Future<proto.CompileDDCResponse> _compileDDC(String source) => null;

  @override
  Future<proto.CompileResponse> _compileDart2js(String source,
          {bool returnSourceMap = false}) =>
      null;

  @override
  Future<void> _setCache(String query, String result) => null;

  @override
  bool get analysisServersRunning => true;

  @override
  Future<void> init() => null;

  @override
  bool get isHealthy => true;

  @override
  bool get isRestarting => false;

  @override
  Future<dynamic> shutdown() => null;

  @override
  AnalysisServersWrapper get _analysisServers => null;

  @override
  Compiler get _compiler => null;

  @override
  ServerCache get _cache => null;

  @override
  ServerContainer get _container => null;

  @override
  set _analysisServers(AnalysisServersWrapper analysisServers) => null;

  @override
  set _compiler(Compiler compiler) => null;
}

final JsonEncoder _jsonEncoder = const JsonEncoder.withIndent('  ');

class CommonServerImpl {
  final ServerContainer _container;
  final ServerCache _cache;
  final bool _nullSafety;

  Compiler _compiler;
  AnalysisServersWrapper _analysisServers;

  // Restarting and health status of the two Analysis Servers
  bool get analysisServersRunning => _analysisServers.running;
  bool get isRestarting => _analysisServers.isRestarting;
  bool get isHealthy => _analysisServers.isHealthy;

  CommonServerImpl(
    this._container,
    this._cache,
    this._nullSafety,
  ) {
    hierarchicalLoggingEnabled = true;
    log.level = Level.ALL;
  }

  Future<void> init() async {
    log.info('Beginning CommonServer init().');
    _analysisServers = AnalysisServersWrapper(_nullSafety);
    _compiler = Compiler(Sdk(), _nullSafety);

    await _compiler.warmup();
    await _analysisServers.warmup();
  }

  Future<dynamic> shutdown() {
    return Future.wait(<Future<dynamic>>[
      _analysisServers.shutdown(),
      _compiler.dispose(),
      Future<dynamic>.sync(_cache.shutdown)
    ]).timeout(const Duration(minutes: 1));
  }

  Future<proto.AnalysisResults> analyze(proto.SourceRequest request) {
    if (!request.hasSource()) {
      throw BadRequest('Missing parameter: \'source\'');
    }

    return _analysisServers.analyze(request.source);
  }

  Future<proto.CompileResponse> compile(proto.CompileRequest request) {
    if (!request.hasSource()) {
      throw BadRequest('Missing parameter: \'source\'');
    }

    return _compileDart2js(request.source,
        returnSourceMap: request.returnSourceMap ?? false);
  }

  Future<proto.CompileDDCResponse> compileDDC(proto.CompileDDCRequest request) {
    if (!request.hasSource()) {
      throw BadRequest('Missing parameter: \'source\'');
    }

    return _compileDDC(request.source);
  }

  Future<proto.CompleteResponse> complete(proto.SourceRequest request) {
    if (!request.hasSource()) {
      throw BadRequest('Missing parameter: \'source\'');
    }
    if (!request.hasOffset()) {
      throw BadRequest('Missing parameter: \'offset\'');
    }

    return _analysisServers.complete(request.source, request.offset);
  }

  Future<proto.FixesResponse> fixes(proto.SourceRequest request) {
    if (!request.hasSource()) {
      throw BadRequest('Missing parameter: \'source\'');
    }
    if (!request.hasOffset()) {
      throw BadRequest('Missing parameter: \'offset\'');
    }

    return _analysisServers.getFixes(request.source, request.offset);
  }

  Future<proto.AssistsResponse> assists(proto.SourceRequest request) {
    if (!request.hasSource()) {
      throw BadRequest('Missing parameter: \'source\'');
    }
    if (!request.hasOffset()) {
      throw BadRequest('Missing parameter: \'offset\'');
    }

    return _analysisServers.getAssists(request.source, request.offset);
  }

  Future<proto.FormatResponse> format(proto.SourceRequest request) {
    if (!request.hasSource()) {
      throw BadRequest('Missing parameter: \'source\'');
    }

    return _analysisServers.format(request.source, request.offset ?? 0);
  }

  Future<proto.DocumentResponse> document(proto.SourceRequest request) async {
    if (!request.hasSource()) {
      throw BadRequest('Missing parameter: \'source\'');
    }
    if (!request.hasOffset()) {
      throw BadRequest('Missing parameter: \'offset\'');
    }

    return proto.DocumentResponse()
      ..info.addAll(
          await _analysisServers.dartdoc(request.source, request.offset) ??
              <String, String>{});
  }

  Future<proto.VersionResponse> version(proto.VersionRequest _) {
    final sdk = Sdk();
    return Future<proto.VersionResponse>.value(
      proto.VersionResponse()
        ..sdkVersion = sdk.version
        ..sdkVersionFull = sdk.versionFull
        ..runtimeVersion = vmVersion
        ..servicesVersion = servicesVersion
        ..appEngineVersion = _container.version
        ..flutterDartVersion = sdk.version
        ..flutterDartVersionFull = sdk.versionFull
        ..flutterVersion = sdk.flutterVersion,
    );
  }

  Future<proto.CompileResponse> _compileDart2js(
    String source, {
    bool returnSourceMap = false,
  }) async {
    try {
      final sourceHash = _hashSource(source);
      final memCacheKey = '%%COMPILE:v0'
          ':returnSourceMap:$returnSourceMap:source:$sourceHash';

      final result = await _checkCache(memCacheKey);
      if (result != null) {
        log.info('CACHE: Cache hit for compileDart2js');
        final resultObj = const JsonDecoder().convert(result);
        final response = proto.CompileResponse()
          ..result = resultObj['compiledJS'] as String;
        if (resultObj['sourceMap'] != null) {
          response.sourceMap = resultObj['sourceMap'] as String;
        }
        return response;
      }

      log.info('CACHE: MISS for compileDart2js');
      final watch = Stopwatch()..start();

      final results =
          await _compiler.compile(source, returnSourceMap: returnSourceMap);

      if (results.hasOutput) {
        final lineCount = source.split('\n').length;
        final outputSize = (results.compiledJS.length / 1024).ceil();
        final ms = watch.elapsedMilliseconds;
        log.info('PERF: Compiled $lineCount lines of Dart into '
            '${outputSize}kb of JavaScript in ${ms}ms using dart2js.');
        final sourceMap = returnSourceMap ? results.sourceMap : null;

        final cachedResult = const JsonEncoder().convert(<String, String>{
          'compiledJS': results.compiledJS,
          'sourceMap': sourceMap,
        });
        // Don't block on cache set.
        unawaited(_setCache(memCacheKey, cachedResult));
        final compileResponse = proto.CompileResponse();
        compileResponse.result = results.compiledJS;
        if (sourceMap != null) {
          compileResponse.sourceMap = sourceMap;
        }
        return compileResponse;
      } else {
        final problems = results.problems;
        final errors = problems.map(_printCompileProblem).join('\n');
        throw BadRequest(errors);
      }
    } catch (e, st) {
      if (e is! BadRequest) {
        log.severe('Error during compile (dart2js) on "$source"', e, st);
      }
      rethrow;
    }
  }

  Future<proto.CompileDDCResponse> _compileDDC(String source) async {
    try {
      final sourceHash = _hashSource(source);
      final memCacheKey = '%%COMPILE_DDC:v0:source:$sourceHash';

      final result = await _checkCache(memCacheKey);
      if (result != null) {
        log.info('CACHE: Cache hit for compileDDC');
        final resultObj = const JsonDecoder().convert(result);
        return proto.CompileDDCResponse()
          ..result = resultObj['compiledJS'] as String
          ..modulesBaseUrl = resultObj['modulesBaseUrl'] as String;
      }

      log.info('CACHE: MISS for compileDDC');
      final watch = Stopwatch()..start();

      final results = await _compiler.compileDDC(source);

      if (results.hasOutput) {
        final lineCount = source.split('\n').length;
        final outputSize = (results.compiledJS.length / 1024).ceil();
        final ms = watch.elapsedMilliseconds;
        log.info('PERF: Compiled $lineCount lines of Dart into '
            '${outputSize}kb of JavaScript in ${ms}ms using DDC.');

        final cachedResult = const JsonEncoder().convert(<String, String>{
          'compiledJS': results.compiledJS,
          'modulesBaseUrl': results.modulesBaseUrl,
        });
        // Don't block on cache set.
        unawaited(_setCache(memCacheKey, cachedResult));
        return proto.CompileDDCResponse()
          ..result = results.compiledJS
          ..modulesBaseUrl = results.modulesBaseUrl;
      } else {
        final problems = results.problems;
        final errors = problems.map(_printCompileProblem).join('\n');
        throw BadRequest(errors);
      }
    } catch (e, st) {
      if (e is! BadRequest) {
        log.severe('Error during compile (DDC) on "$source"', e, st);
      }
      rethrow;
    }
  }

  Future<String> _checkCache(String query) => _cache.get(query);

  Future<void> _setCache(String query, String result) =>
      _cache.set(query, result, expiration: _standardExpiration);
}

String _printCompileProblem(CompilationProblem problem) => problem.message;

String _hashSource(String str) {
  return sha1.convert(str.codeUnits).toString();
}
