// 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 services_gae;

import 'dart:io' as io;
import 'dart:math';

import 'package:appengine/appengine.dart' as ae;
import 'package:args/args.dart';
import 'package:logging/logging.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;

import 'src/common_server_api.dart';
import 'src/common_server_impl.dart';
import 'src/sdk_manager.dart';
import 'src/server_cache.dart';

const String _API_PREFIX = '/api/dartservices/';
const String _livenessCheck = '/liveness_check';
const String _readinessCheck = '/readiness_check';

// Serve content for 1.5 hours, +- 30 minutes.
final DateTime _serveUntil = DateTime.now()
    .add(Duration(hours: 1))
    .add(Duration(minutes: Random().nextInt(60)));

final Logger _logger = Logger('gae_server');

void main(List<String> args) {
  final parser = ArgParser()
    ..addOption('proxy-target',
        help: 'URL base to proxy compilation requests to')
    ..addOption('port',
        abbr: 'p', defaultsTo: '8080', help: 'Port to attach to');
  final results = parser.parse(args);

  final gaePort = int.tryParse(results['port'] as String ?? '') ?? 8080;

  if (SdkManager.sdk.sdkPath == null) {
    throw 'No Dart SDK is available; set the DART_SDK env var.';
  }

  // Log to stdout/stderr.  AppEngine's logging package is disabled in 0.6.0
  // and AppEngine copies stdout/stderr to the dashboards.
  _logger.onRecord.listen((LogRecord rec) {
    final out = ('${rec.level.name}: ${rec.time}: ${rec.message}\n');
    if (rec.level > Level.INFO) {
      io.stderr.write(out);
    } else {
      io.stdout.write(out);
    }
  });
  log.info('''Initializing dart-services:
    --port: $gaePort
    --proxy-target: ${results['proxy-target']}
    sdkPath: ${SdkManager.sdk?.sdkPath}
    \$REDIS_SERVER_URI: ${io.Platform.environment['REDIS_SERVER_URI']}
    \$GAE_VERSION: ${io.Platform.environment['GAE_VERSION']}
  ''');

  final server = GaeServer(io.Platform.environment['REDIS_SERVER_URI'],
      results['proxy-target'].toString());
  server.start(gaePort);
}

class GaeServer {
  final String redisServerUri;

  CommonServerImpl commonServerImpl;
  CommonServerApi commonServerApi;
  bool proxying = false;

  GaeServer(this.redisServerUri, String proxyTarget) {
    hierarchicalLoggingEnabled = true;
    recordStackTraceAtLevel = Level.SEVERE;

    _logger.level = Level.ALL;

    if (proxyTarget != null && proxyTarget.isNotEmpty) {
      commonServerImpl = CommonServerImplProxy(proxyTarget);
      proxying = true;
    } else {
      commonServerImpl = CommonServerImpl(
        GaeServerContainer(),
        redisServerUri == null
            ? InMemoryCache()
            : RedisCache(
                redisServerUri,
                io.Platform.environment['GAE_VERSION'],
              ),
      );
    }
    commonServerApi = CommonServerApi(commonServerImpl);
  }

  Future<dynamic> start([int gaePort = 8080]) async {
    await commonServerImpl.init();
    return ae.runAppEngine(requestHandler, port: gaePort);
  }

  Future<void> requestHandler(io.HttpRequest request) async {
    request.response.headers
      ..add('Access-Control-Allow-Origin', '*')
      ..add('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
      ..add('Access-Control-Allow-Headers',
          'Origin, X-Requested-With, Content-Type, Accept');

    if (request.method == 'OPTIONS') {
      await _processOptionsRequest(request);
    } else if (request.uri.path == _readinessCheck) {
      await _processReadinessRequest(request);
    } else if (request.uri.path == _livenessCheck) {
      await _processLivenessRequest(request);
    } else if (request.uri.path.startsWith(_API_PREFIX)) {
      await shelf_io.handleRequest(request, commonServerApi.router);
    } else {
      await _processDefaultRequest(request);
    }
  }

  Future<void> _processOptionsRequest(io.HttpRequest request) async {
    final statusCode = io.HttpStatus.ok;
    request.response.statusCode = statusCode;
    await request.response.close();
  }

  Future<void> _processReadinessRequest(io.HttpRequest request) async {
    _logger.info('Processing readiness check');
    if (proxying) {
      request.response.statusCode = io.HttpStatus.ok;
    } else if (!commonServerImpl.isRestarting &&
        DateTime.now().isBefore(_serveUntil)) {
      request.response.statusCode = io.HttpStatus.ok;
    } else {
      request.response.statusCode = io.HttpStatus.serviceUnavailable;
      _logger.severe('CommonServer not running - failing readiness check.');
    }

    await request.response.close();
  }

  Future<void> _processLivenessRequest(io.HttpRequest request) async {
    _logger.info('Processing liveness check');
    if (proxying) {
      request.response.statusCode = io.HttpStatus.ok;
    } else if (!commonServerImpl.isHealthy ||
        DateTime.now().isAfter(_serveUntil)) {
      _logger.severe('CommonServer is no longer healthy.'
          ' Intentionally failing health check.');
      request.response.statusCode = io.HttpStatus.serviceUnavailable;
    } else {
      try {
        final tempDir = await io.Directory.systemTemp.createTemp('healthz');
        try {
          final file = io.File('${tempDir.path}/livecheck.txt');
          await file.writeAsString('testing123\n' * 1000, flush: true);
          final stat = await file.stat();
          if (stat.size > 10000) {
            _logger.info('CommonServer healthy and file system working.'
                ' Passing health check.');
            request.response.statusCode = io.HttpStatus.ok;
          } else {
            _logger.severe('CommonServer healthy, but filesystem is not.'
                ' Intentionally failing health check.');
            request.response.statusCode = io.HttpStatus.serviceUnavailable;
          }
        } finally {
          await tempDir.delete(recursive: true);
        }
      } catch (e) {
        _logger.severe('CommonServer healthy, but failed to create temporary'
            ' file: $e');
        request.response.statusCode = io.HttpStatus.serviceUnavailable;
      }
    }

    await request.response.close();
  }

  Future<void> _processDefaultRequest(io.HttpRequest request) async {
    request.response.statusCode = io.HttpStatus.notFound;
    await request.response.close();
  }
}

class GaeServerContainer implements ServerContainer {
  @override
  String get version => io.Platform.version;
}
