// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io';

import 'package:appengine/appengine.dart';
import 'package:cocoon_service/cocoon_service.dart';
import 'package:cocoon_service/src/model/appengine/service_account_info.dart';
import 'package:cocoon_service/src/service/github_checks_service.dart';
import 'package:cocoon_service/src/service/github_status_service.dart';
import 'package:cocoon_service/src/service/luci_build_service.dart';
import 'package:gcloud/db.dart';

/// For local development, you might want to set this to true.
const String _kCocoonUseInMemoryCache = 'COCOON_USE_IN_MEMORY_CACHE';

Future<void> main() async {
  await withAppEngineServices(() async {
    final bool inMemoryCache =
        Platform.environment[_kCocoonUseInMemoryCache] == 'true';
    final CacheService cache = CacheService(inMemory: inMemoryCache);

    final Config config = Config(dbService, cache);
    final AuthenticationProvider authProvider = AuthenticationProvider(config);
    final BuildBucketClient buildBucketClient = BuildBucketClient(
      accessTokenService: AccessTokenService.defaultProvider(config),
    );
    final ServiceAccountInfo serviceAccountInfo =
        await config.deviceLabServiceAccount;

    /// LUCI service class to communicate with buildBucket service.
    final LuciBuildService luciBuildService = LuciBuildService(
      config,
      buildBucketClient,
      serviceAccountInfo,
    );

    /// Github status service to update the state of the build
    /// in the Github UI.
    final GithubStatusService githubStatusService = GithubStatusService(
      config,
      luciBuildService,
    );

    /// Github checks api service used to provide luci test execution status on the Github UI.
    final GithubChecksService githubChecksService = GithubChecksService(
      config,
    );

    final Map<String, RequestHandler<dynamic>> handlers =
        <String, RequestHandler<dynamic>>{
      '/api/append-log': AppendLog(config, authProvider),
      '/api/authorize-agent': AuthorizeAgent(config, authProvider),
      '/api/check-waiting-pull-requests':
          CheckForWaitingPullRequests(config, authProvider),
      '/api/create-agent': CreateAgent(config, authProvider),
      '/api/get-authentication-status':
          GetAuthenticationStatus(config, authProvider),
      '/api/get-log': GetLog(config, authProvider),
      '/api/github-webhook-pullrequest': GithubWebhook(
        config,
        buildBucketClient,
        luciBuildService,
        githubStatusService,
        githubChecksService,
      ),
      '/api/luci-status-handler': LuciStatusHandler(config, buildBucketClient),
      '/api/push-build-status-to-github':
          PushBuildStatusToGithub(config, authProvider),
      '/api/push-gold-status-to-github':
          PushGoldStatusToGithub(config, authProvider),
      '/api/push-engine-build-status-to-github':
          PushEngineStatusToGithub(config, authProvider),
      '/api/refresh-chromebot-status':
          RefreshChromebotStatus(config, authProvider),
      '/api/refresh-github-commits': RefreshGithubCommits(config, authProvider),
      '/api/refresh-cirrus-status': RefreshCirrusStatus(config, authProvider),
      '/api/reserve-task': ReserveTask(config, authProvider),
      '/api/reset-devicelab-task': ResetDevicelabTask(config, authProvider),
      '/api/update-agent-health': UpdateAgentHealth(config, authProvider),
      '/api/update-agent-health-history':
          UpdateAgentHealthHistory(config, authProvider),
      '/api/update-benchmark-targets':
          UpdateBenchmarkTargets(config, authProvider),
      '/api/update-task-status': UpdateTaskStatus(config, authProvider),
      '/api/update-timeseries': UpdateTimeSeries(config, authProvider),
      '/api/vacuum-clean': VacuumClean(config, authProvider),
      '/api/public/build-status': CacheRequestHandler<Body>(
        cache: cache,
        config: config,
        delegate: GetBuildStatus(config),
        ttl: const Duration(seconds: 15),
      ),
      '/api/public/get-benchmarks': CacheRequestHandler<Body>(
        cache: cache,
        config: config,
        delegate: GetBenchmarks(config),
        ttl: const Duration(minutes: 15),
      ),
      '/api/public/get-status': CacheRequestHandler<Body>(
        cache: cache,
        config: config,
        delegate: GetStatus(config),
      ),
      '/api/public/get-timeseries-history': GetTimeSeriesHistory(config),
      '/api/public/get-branches': CacheRequestHandler<Body>(
        cache: cache,
        config: config,
        delegate: GetBranches(config),
        ttl: const Duration(minutes: 15),
      ),
    };

    return await runAppEngine((HttpRequest request) async {
      final RequestHandler<dynamic> handler = handlers[request.uri.path];
      if (handler != null) {
        await handler.service(request);
      } else {
        final String filePath = request.uri.toFilePath();

        const List<String> indexRedirects = <String>['/build.html'];
        if (indexRedirects.contains(filePath)) {
          request.response.statusCode = HttpStatus.permanentRedirect;
          // The separate HTML files are remnants from when Cocoon was written
          // with an Angular Dart frontend.
          final String flutterRouteName = filePath.replaceFirst('.html', '');
          return await request.response
              .redirect(Uri.parse('/#$flutterRouteName'));
        }

        await StaticFileHandler(filePath, config: config).service(request);
      }
    }, onAcceptingConnections: (InternetAddress address, int port) {
      final String host = address.isLoopback ? 'localhost' : address.host;
      print('Serving requests at $host:$port');
    });
  });
}
