// Copyright 2014 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:async';

import 'package:meta/meta.dart';

import '../persistent_tool_state.dart';
import 'io.dart';
import 'net.dart';
import 'platform.dart';

class BotDetector {
  BotDetector({
    @required HttpClientFactory httpClientFactory,
    @required Platform platform,
    @required PersistentToolState persistentToolState,
  }) :
    _platform = platform,
    _azureDetector = AzureDetector(
      httpClientFactory: httpClientFactory,
    ),
    _persistentToolState = persistentToolState;

  final Platform _platform;
  final AzureDetector _azureDetector;
  final PersistentToolState _persistentToolState;

  Future<bool> get isRunningOnBot async {
    if (_persistentToolState.isRunningOnBot != null) {
      return _persistentToolState.isRunningOnBot;
    }
    if (
      // Explicitly stated to not be a bot.
      _platform.environment['BOT'] == 'false'

      // Set by the IDEs to the IDE name, so a strong signal that this is not a bot.
      || _platform.environment.containsKey('FLUTTER_HOST')
      // When set, GA logs to a local file (normally for tests) so we don't need to filter.
      || _platform.environment.containsKey('FLUTTER_ANALYTICS_LOG_FILE')
    ) {
      return _persistentToolState.isRunningOnBot = false;
    }

    return _persistentToolState.isRunningOnBot = _platform.environment['BOT'] == 'true'

      // https://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables
      || _platform.environment['TRAVIS'] == 'true'
      || _platform.environment['CONTINUOUS_INTEGRATION'] == 'true'
      || _platform.environment.containsKey('CI') // Travis and AppVeyor

      // https://www.appveyor.com/docs/environment-variables/
      || _platform.environment.containsKey('APPVEYOR')

      // https://cirrus-ci.org/guide/writing-tasks/#environment-variables
      || _platform.environment.containsKey('CIRRUS_CI')

      // https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html
      || (_platform.environment.containsKey('AWS_REGION') &&
          _platform.environment.containsKey('CODEBUILD_INITIATOR'))

      // https://wiki.jenkins.io/display/JENKINS/Building+a+software+project#Buildingasoftwareproject-belowJenkinsSetEnvironmentVariables
      || _platform.environment.containsKey('JENKINS_URL')

      // https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
      || _platform.environment.containsKey('GITHUB_ACTIONS')

      // Properties on Flutter's Chrome Infra bots.
      || _platform.environment['CHROME_HEADLESS'] == '1'
      || _platform.environment.containsKey('BUILDBOT_BUILDERNAME')
      || _platform.environment.containsKey('SWARMING_TASK_ID')

      // Property when running on borg.
      || _platform.environment.containsKey('BORG_ALLOC_DIR')

      // Property when running on Azure.
      || await _azureDetector.isRunningOnAzure;
  }
}

// Are we running on Azure?
// https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service
@visibleForTesting
class AzureDetector {
  AzureDetector({
    @required HttpClientFactory httpClientFactory,
  }) : _httpClientFactory = httpClientFactory;

  static const String _serviceUrl = 'http://169.254.169.254/metadata/instance';

  final HttpClientFactory _httpClientFactory;

  bool _isRunningOnAzure;

  Future<bool> get isRunningOnAzure async {
    if (_isRunningOnAzure != null) {
      return _isRunningOnAzure;
    }
    const Duration connectionTimeout = Duration(milliseconds: 250);
    const Duration requestTimeout = Duration(seconds: 1);
    final HttpClient client = _httpClientFactory()
      ..connectionTimeout = connectionTimeout;
    try {
      final HttpClientRequest request = await client.getUrl(
        Uri.parse(_serviceUrl),
      ).timeout(requestTimeout);
      request.headers.add('Metadata', true);
      await request.close();
    } on SocketException {
      // If there is an error on the socket, it probably means that we are not
      // running on Azure.
      return _isRunningOnAzure = false;
    } on HttpException {
      // If the connection gets set up, but encounters an error condition, it
      // still means we're on Azure.
      return _isRunningOnAzure = true;
    } on TimeoutException {
      // The HttpClient connected to a host, but it did not respond in a timely
      // fashion. Assume we are not on a bot.
      return _isRunningOnAzure = false;
    } on OSError {
      // The HttpClient might be running in a WSL1 environment.
      return _isRunningOnAzure = false;
    }
    // We got a response. We're running on Azure.
    return _isRunningOnAzure = true;
  }
}
