// 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 'package:json_annotation/json_annotation.dart';

import '../../request_handling/body.dart';
import '../common/json_converters.dart';

part 'push_message.g.dart';

/// A Cloud PubSub push message.
///
/// For example:
/// ```json
/// {
///   "message": {
///     "attributes": {
///       "key": "value"
///     },
///     "data": "SGVsbG8gQ2xvdWQgUHViL1N1YiEgSGVyZSBpcyBteSBtZXNzYWdlIQ==",
///     "messageId": "136969346945"
///   },
///   "subscription": "projects/myproject/subscriptions/mysubscription"
/// }
/// ```
///
/// Where `data` is base64 encoded.
///
/// See https://cloud.google.com/pubsub/docs/push#receiving_push_messages
@JsonSerializable(includeIfNull: false)
class PushMessageEnvelope extends JsonBody {
  const PushMessageEnvelope({
    this.message,
    this.subscription,
  });

  static PushMessageEnvelope fromJson(Map<String, dynamic> json) => _$PushMessageEnvelopeFromJson(json);

  /// The message contents.
  final PushMessage? message;

  /// The name of the subscription associated with the delivery.
  final String? subscription;

  @override
  Map<String, dynamic> toJson() => _$PushMessageEnvelopeToJson(this);
}

/// A PubSub push message payload.
@JsonSerializable(includeIfNull: false)
class PushMessage extends JsonBody {
  const PushMessage({
    this.attributes,
    this.data,
    this.messageId,
  });

  static PushMessage fromJson(Map<String, dynamic> json) => _$PushMessageFromJson(json);

  /// PubSub attributes on the message.
  final Map<String, String>? attributes;

  /// The raw string data of the message.
  @Base64Converter()
  final String? data;

  /// A identifier for the message from PubSub.
  final String? messageId;

  @override
  Map<String, dynamic> toJson() => _$PushMessageToJson(this);
}

/// The LUCI build data from a PubSub push message payload.
@JsonSerializable(includeIfNull: false)
class BuildPushMessage extends JsonBody {
  const BuildPushMessage({
    this.build,
    this.hostname,
    this.userData,
  });

  static BuildPushMessage fromJson(Map<String, dynamic> json) => _$BuildPushMessageFromJson(json);

  /// The Build this message is for.
  final Build? build;

  /// The hostname for the build, e.g. `cr-buildbucket.appspot.com`.
  final String? hostname;

  /// User data that was included in the LUCI build request.
  @JsonKey(name: 'user_data')
  final String? userData;

  @override
  Map<String, dynamic> toJson() => _$BuildPushMessageToJson(this);
}

/// See https://github.com/luci/luci-go/blob/master/common/api/buildbucket/buildbucket/v1/buildbucket-gen.go#L332ƒ
@JsonSerializable(includeIfNull: false)
class Build extends JsonBody {
  const Build({
    this.bucket,
    this.canary,
    this.canaryPreference,
    this.cancelationReason,
    this.completedTimestamp,
    this.createdBy,
    this.createdTimestamp,
    this.failureReason,
    this.experimental,
    this.id,
    this.buildParameters,
    this.project,
    this.result,
    this.resultDetails,
    this.serviceAccount,
    this.startedTimestamp,
    this.status,
    this.tags,
    this.updatedTimestamp,
    this.utcNowTimestamp,
    this.url,
  });

  static Build fromJson(Map<String, dynamic> json) => _$BuildFromJson(json);

  /// The BuildBucket name.
  final String? bucket;

  /// Whether carnary hardware was used.
  final bool? canary;

  /// The canary preference for `canary`.
  @JsonKey(name: 'canary_preference')
  final CanaryPreference? canaryPreference;

  /// The reason for canceling the build.
  @JsonKey(name: 'cancelation_reason')
  final CancelationReason? cancelationReason;

  /// The completion time of the build.
  @JsonKey(name: 'completed_ts')
  @MicrosecondsSinceEpochConverter()
  final DateTime? completedTimestamp;

  /// The user who created the build.
  @JsonKey(name: 'created_by')
  final String? createdBy;

  /// The creation time of the build.
  @JsonKey(name: 'created_ts')
  @MicrosecondsSinceEpochConverter()
  final DateTime? createdTimestamp;

  /// Whether the build was experimental or not.
  final bool? experimental;

  /// The reason the build failed, if it failed.
  @JsonKey(name: 'failure_reason')
  final FailureReason? failureReason;

  /// The unique BuildBucket ID for the build.
  final String? id;

  /// Parameters passed to the build.
  @JsonKey(name: 'parameters_json')
  @NestedJsonConverter()
  final Map<String, dynamic>? buildParameters;

  /// The BuildBucket project for the build, e.g. `flutter`.
  final String? project;

  /// The result of the build.
  ///
  /// If [Result.canceled], [cancelationReason] will be populated.
  ///
  /// If [Result.failure], [failureReason] will be populated.
  final Result? result;

  /// A JSON object that contains additional build information based on the
  /// result.
  @JsonKey(name: 'result_details_json')
  @NestedJsonConverter()
  final Map<String, dynamic>? resultDetails;

  /// The service account used for the build.
  @JsonKey(name: 'service_account')
  final String? serviceAccount;

  /// The time of the build start.
  @JsonKey(name: 'started_ts')
  @MicrosecondsSinceEpochConverter()
  final DateTime? startedTimestamp;

  /// The [Status] of the build.
  ///
  /// If [Status.completed], [result] will be populated.
  final Status? status;

  /// The swarming tags for the build.
  final List<String>? tags;

  /// Returns all tags matching the prefix.
  ///
  /// For example, to get the `buildset` tag(s), call `tagsByName('buildset')`;
  /// to get the `swarming_tag:os`, call `tagsByName('swarming_tag:os')`.
  List<String> tagsByName(String prefix) {
    return tags!
        .where((String tag) => tag.startsWith('$prefix:'))
        .map<String>((String tag) => tag.substring(prefix.length + 1))
        .toList();
  }

  /// The time of the last update to this information.
  @JsonKey(name: 'updated_ts')
  @MicrosecondsSinceEpochConverter()
  final DateTime? updatedTimestamp;

  /// The URL of the build.
  final String? url;

  /// The time used as UTC now for reference to other times in this message.
  @JsonKey(name: 'utcnow_ts')
  @MicrosecondsSinceEpochConverter()
  final DateTime? utcNowTimestamp;

  @override
  Map<String, dynamic> toJson() => _$BuildToJson(this);
}

/// The method to select whether canary hardware was chosen for a build.
enum CanaryPreference {
  @JsonValue('AUTO')
  auto,
  @JsonValue('CANARY')
  canary,
  @JsonValue('PROD')
  prod,
}

/// The reason for canceling a build.
enum CancelationReason {
  @JsonValue('CANCELED_EXPLICITLY')
  canceledExplicitly,
  @JsonValue('TIMEOUT')
  timeout,
}

/// The reason a build failed.
enum FailureReason {
  @JsonValue('BUILDBUCKET_FAILURE')
  buildbucketFailure,
  @JsonValue('BUILD_FAILURE')
  buildFailure,
  @JsonValue('INFRA_FAILURE')
  infraFailure,
  @JsonValue('INVALID_BUILD_DEFINITION')
  invalidBuildDefinition,
}

/// The final result of a build, if its [Status] is [Status.completed].
enum Result {
  @JsonValue('CANCELED')
  canceled,
  @JsonValue('FAILURE')
  failure,
  @JsonValue('INFRA_FAILURE')
  infraFailure,
  @JsonValue('SUCCESS')
  success,
}

/// The current status of a build.
///
/// If [Status.completed], then a [Result] will be present as well.
enum Status {
  @JsonValue('COMPLETED')
  completed,
  @JsonValue('SCHEDULED')
  scheduled,
  @JsonValue('STARTED')
  started,
}
