// Copyright (c) 2017, 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.

import 'util.dart';

/// The [Uri] of a build step stdio log split into its subparts.
class BuildUri {
  final String botName;
  final int buildNumber;
  final String stepName;

  factory BuildUri(Uri uri) {
    if (uri.host == "logs.chromium.org") {
      RegExp logdogBuilderRegExp = new RegExp(
          r"^.*\/client\.dart\/(.*)\/(\d*)\/\+\/recipes\/steps\/(.*)\/0.*$");
      var match =
          logdogBuilderRegExp.firstMatch(Uri.decodeFull(uri.toString()));
      return new BuildUri.fromData(
          match.group(1), int.parse(match.group(2)), match.group(3));
    } else {
      List<String> parts = split(Uri.decodeFull(uri.path),
          ['/builders/', '/builds/', '/steps/', '/logs/']);
      String botName = parts[1];
      int buildNumber = int.parse(parts[2]);
      String stepName = parts[3];
      return new BuildUri.fromData(botName, buildNumber, stepName);
    }
  }

  factory BuildUri.fromUrl(String url) {
    if (!url.endsWith('/text') && !url.contains("logs.chromium.org")) {
      // Use the text version of the stdio log.
      url += '/text';
    }
    return new BuildUri(Uri.parse(url));
  }

  BuildUri.fromData(this.botName, this.buildNumber, this.stepName);

  BuildUri withBuildNumber(int buildNumber) {
    return new BuildUri.fromData(botName, buildNumber, stepName);
  }

  int get absoluteBuildNumber => buildNumber >= 0 ? buildNumber : null;

  String get shortBuildName => '$botName/$stepName';

  String get buildName =>
      '/builders/$botName/builds/$buildNumber/steps/$stepName';

  String get path => '/p/client.dart$buildName/logs/stdio/text';

  /// Returns the path used in logdog for this build uri.
  ///
  /// Since logdog only supports absolute build numbers, [buildNumber] must be
  /// non-negative. A [StateError] is thrown, otherwise.
  String get logdogPath {
    if (buildNumber < 0)
      throw new StateError('BuildUri $buildName must have a non-negative build '
          'number to a valid logdog path.');
    return 'bb/client.dart/$botName/$buildNumber/+/recipes/steps/'
        '${stepName.replaceAll(' ', '_')}/0/stdout';
  }

  /// Creates the [Uri] for this build step stdio log.
  Uri toUri() {
    return new Uri(scheme: 'https', host: 'build.chromium.org', path: path);
  }

  /// Returns the [BuildUri] the previous build of this build step.
  BuildUri prev() {
    return new BuildUri.fromData(botName, buildNumber - 1, stepName);
  }

  String toString() {
    return buildName;
  }
}

/// Id for a test on a specific configuration, for instance
/// `dart2js-chrome release_x64 co19/Language/Metadata/before_function_t07`.
class TestConfiguration {
  final String configName;
  final String archName;
  final String testName;

  TestConfiguration(this.configName, this.archName, this.testName);

  String toString() {
    return '$configName $archName $testName';
  }

  int get hashCode =>
      configName.hashCode * 13 +
      archName.hashCode * 17 +
      testName.hashCode * 19;

  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! TestConfiguration) return false;
    return configName == other.configName &&
        archName == other.archName &&
        testName == other.testName;
  }
}

/// The results of a build step.
class BuildResult {
  final BuildUri buildUri;

  /// The absolute build number, if found.
  ///
  /// The [buildUri] can be created with a relative build number, such as `-2`
  /// which means the second-to-last build. The absolute build number, a
  /// positive number, is read from the build results.
  final int buildNumber;

  final String buildRevision;

  final List<TestStatus> _results;
  final List<TestFailure> _failures;
  final List<Timing> _timings;

  BuildResult(this.buildUri, this.buildNumber, this.buildRevision,
      this._results, this._failures, this._timings);

  /// `true` of the build result has test failures.
  bool get hasFailures => _failures.isNotEmpty;

  /// Returns the top-20 timings found in the build log.
  Iterable<Timing> get timings => _timings;

  /// Returns the [TestStatus] for all tests.
  Iterable<TestStatus> get results => _results;

  /// Returns the [TestFailure]s for tests that timed out.
  Iterable<TestFailure> get timeouts {
    return _failures
        .where((TestFailure failure) => failure.actual == 'Timeout');
  }

  /// Returns the [TestFailure]s for failing tests that did not time out.
  Iterable<TestFailure> get errors {
    return _failures
        .where((TestFailure failure) => failure.actual != 'Timeout');
  }

  /// Returns all [TestFailure]s.
  Iterable<TestFailure> get failures => _failures;

  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.write('$buildUri\n');
    sb.write('Failures:\n${_failures.join('\n-----\n')}\n');
    sb.write('\nTimings:\n${_timings.join('\n')}');
    return sb.toString();
  }
}

/// Test failure data derived from the test failure summary in the build step
/// stdio log.
class TestFailure {
  final BuildUri uri;
  final TestConfiguration id;
  final String expected;
  final String actual;
  final String text;

  factory TestFailure(BuildUri uri, List<String> lines) {
    List<String> parts = split(lines.first, ['FAILED: ', ' ', ' ']);
    String configName = parts[1];
    String archName = parts[2];
    String testName = parts[3];
    TestConfiguration id =
        new TestConfiguration(configName, archName, testName);
    String expected = split(lines[1], ['Expected: '])[1].trim();
    String actual = split(lines[2], ['Actual: '])[1].trim();
    return new TestFailure.internal(
        uri, id, expected, actual, lines.skip(3).join('\n'));
  }

  TestFailure.internal(
      this.uri, this.id, this.expected, this.actual, this.text);

  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.write('FAILED: $id\n');
    sb.write('Expected: $expected\n');
    sb.write('Actual: $actual\n');
    sb.write(text);
    return sb.toString();
  }
}

/// Id for a single test step, for instance the compilation and run steps of
/// a test.
class TestStep {
  final String stepName;
  final TestConfiguration id;

  TestStep(this.stepName, this.id);

  String toString() {
    return '$stepName - $id';
  }

  int get hashCode => stepName.hashCode * 13 + id.hashCode * 17;

  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! TestStep) return false;
    return stepName == other.stepName && id == other.id;
  }
}

/// The timing result for a single test step.
class Timing {
  final BuildUri uri;
  final String time;
  final TestStep step;

  Timing(this.uri, this.time, this.step);

  String toString() {
    return '$time - $step';
  }
}

/// The result of a single test for a single test step.
class TestStatus {
  final TestConfiguration config;
  final String status;

  TestStatus(this.config, this.status);

  String toString() => '$config: $status';
}
