// 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';
import '../google/grpc.dart';

part 'buildbucket.g.dart';

// The classes in this file are based on protos found in:
// https://chromium.googlesource.com/infra/luci/luci-go/+/master/buildbucket/proto/build.proto
// https://chromium.googlesource.com/infra/luci/luci-go/+/master/buildbucket/proto/common.proto
// https://chromium.googlesource.com/infra/luci/luci-go/+/master/buildbucket/proto/rpc.proto
//
// The `fromJson` methods in this class are static rather than factories so that
// they can be passed as arguments to other functions looking for a parser.

/// A request for the Batch RPC.
///
/// This message can be used to find, get, schedule, or cancel multiple builds.
@JsonSerializable(includeIfNull: false)
class BatchRequest extends JsonBody {
  /// Creates a request for the Batch RPC.
  const BatchRequest({
    this.requests,
  });

  /// Creates a [BatchRequest] from JSON.
  static BatchRequest fromJson(Map<String, dynamic> json) => _$BatchRequestFromJson(json);

  /// The batch of [Request]s to make.
  final List<Request>? requests;

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

  @override
  String toString() {
    return requests.toString();
  }
}

/// A container for one request in a batch.
///
/// A single request must contain only one object.
@JsonSerializable(includeIfNull: false)
class Request extends JsonBody {
  /// Creates a request for the Batch RPC.
  ///
  /// One and only one argument should be set.
  const Request({
    this.getBuild,
    this.searchBuilds,
    this.scheduleBuild,
    this.cancelBuild,
  }) : assert(
          (getBuild != null && searchBuilds == null && scheduleBuild == null && cancelBuild == null) ||
              (getBuild == null && searchBuilds != null && scheduleBuild == null && cancelBuild == null) ||
              (getBuild == null && searchBuilds == null && scheduleBuild != null && cancelBuild == null) ||
              (getBuild == null && searchBuilds == null && scheduleBuild == null && cancelBuild != null),
        );

  /// Creates a [Request] object from JSON.
  static Request fromJson(Map<String, dynamic> json) => _$RequestFromJson(json);

  /// A request to get build information.
  final GetBuildRequest? getBuild;

  /// A request to find builds.
  final SearchBuildsRequest? searchBuilds;

  /// A request to schedule a build.
  ///
  /// All schedule build requests are executed before other requests by LUCI.
  final ScheduleBuildRequest? scheduleBuild;

  /// A request to cancel a build.
  final CancelBuildRequest? cancelBuild;

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

  @override
  String toString() {
    return getBuild?.toString() ??
        searchBuilds?.toString() ??
        scheduleBuild?.toString() ??
        cancelBuild?.toString() ??
        'Unknown build';
  }
}

/// A response from the Batch RPC.
@JsonSerializable(includeIfNull: false)
class BatchResponse extends JsonBody {
  /// Creates a response for the Batch RPC.
  const BatchResponse({
    this.responses,
  });

  /// Creates a [BatchResponse] from JSON.
  static BatchResponse fromJson(Map<String, dynamic>? json) => _$BatchResponseFromJson(json!);

  /// The collected responses from the Batch request.
  final List<Response>? responses;

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

/// An individual response from a batch request.
@JsonSerializable(includeIfNull: false)
class Response extends JsonBody {
  /// Creates a response for the response from the Batch RPC.
  ///
  /// One and only one of these should be set.
  const Response({
    this.getBuild,
    this.searchBuilds,
    this.scheduleBuild,
    this.cancelBuild,
    this.error,
  }) : assert(
          getBuild != null || searchBuilds != null || scheduleBuild != null || cancelBuild != null || error != null,
        );

  /// Creates a [Response] from JSON.
  static Response fromJson(Map<String, dynamic> json) => _$ResponseFromJson(json);

  /// The [Build] response corresponding to a getBuild request.
  final Build? getBuild;

  /// The [SearchBuildsResponse] corresponding to a searchBuilds request.
  final SearchBuildsResponse? searchBuilds;

  /// The [Build] response corresponding to a scheduleBuild request.
  final Build? scheduleBuild;

  /// The [Build] response corresponding to a cancelBuild request.
  final Build? cancelBuild;

  /// Error code of the unsuccessful request.
  final GrpcStatus? error;

  @override
  String toString() {
    if (getBuild != null) {
      return 'getBuild: $getBuild; status: $error';
    } else if (searchBuilds != null) {
      return 'searchBuilds: $searchBuilds; status: $error';
    } else if (scheduleBuild != null) {
      return 'scheduleBuild: $scheduleBuild; status: $error';
    } else if (cancelBuild != null) {
      return 'cancelBuild: $cancelBuild; status: $error';
    }

    return 'No response';
  }

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

/// A request for the GetBuild RPC.
@JsonSerializable(includeIfNull: false)
class GetBuildRequest extends JsonBody {
  /// Creates a request for the GetBuild RPC.
  const GetBuildRequest({
    this.id,
    this.builderId,
    this.buildNumber,
    this.fields,
  }) : assert(
          (id == null && builderId != null && buildNumber != null) ||
              (id != null && builderId == null && buildNumber == null),
        );

  /// Creates a [GetBuildRequest] from JSON.
  static GetBuildRequest fromJson(Map<String, dynamic> json) => _$GetBuildRequestFromJson(json);

  /// The BuildBucket build ID.
  ///
  /// If specified, [builderId] and [buildNumber] must be null.
  final String? id;

  /// The BuildBucket [BuilderId].
  ///
  /// If specified, [buildNumber] must be specified, and [id] must be null.
  @JsonKey(name: 'builder')
  final BuilderId? builderId;

  /// The BuildBucket build number.
  ///
  /// If specified, [builderId] must be specified, and [id] must be null.
  final int? buildNumber;

  /// The list fields to be included in the response.
  ///
  /// This is a comma separated list of Build proto fields to get included
  /// in the response.
  final String? fields;

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

  @override
  String toString() {
    return 'getBuild(id: $id, buildNumber: $buildNumber, field: $fields, builderId: $builderId)';
  }
}

/// A request for the GetBuilder RPC.
@JsonSerializable(includeIfNull: false)
class GetBuilderRequest extends JsonBody {
  /// Creates a request for the GetBuild RPC.
  const GetBuilderRequest({
    this.builderId,
  }) : assert(builderId != null);

  /// Creates a [GetBuilderRequest] from JSON.
  static GetBuilderRequest fromJson(Map<String, dynamic> json) => _$GetBuilderRequestFromJson(json);

  /// The BuildBucket builder ID.
  final BuilderId? builderId;

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

  @override
  String toString() {
    return 'getBuild(builderId: $builderId)';
  }
}

/// Configs of a builder.
@JsonSerializable(includeIfNull: false)
class BuilderConfig extends JsonBody {
  /// Creates a request for the GetBuild RPC.
  const BuilderConfig({
    this.name,
  }) : assert(name != null);

  /// Creates a [GetBuilderRequest] from JSON.
  static BuilderConfig fromJson(Map<String, dynamic> json) => _$BuilderConfigFromJson(json);

  /// The BuildBucket builder ID.
  final String? name;

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

  @override
  String toString() {
    return 'BuilderConfig(name: $name)';
  }
}

/// A configured builder.
///
/// https://chromium.googlesource.com/infra/luci/luci-go/+/main/buildbucket/proto/builder_common.proto
@JsonSerializable(includeIfNull: false)
class BuilderItem extends JsonBody {
  /// Creates a request for the GetBuild RPC.
  const BuilderItem({
    this.id,
    this.config,
  });

  /// Creates a [GetBuilderRequest] from JSON.
  static BuilderItem fromJson(Map<String, dynamic>? json) => _$BuilderItemFromJson(json!);

  /// The BuildBucket builder ID.
  final BuilderId? id;

  /// The BuildBucket builder config.
  final BuilderConfig? config;

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

  @override
  String toString() {
    return 'BuilderItem(builderID: $id, builderConfig: $config)';
  }
}

/// A requrst for the ListBuilders RPC.
@JsonSerializable(includeIfNull: false)
class ListBuildersRequest extends JsonBody {
  /// Creates a request object for the ListBuilders RPC.
  const ListBuildersRequest({
    required this.project,
    this.bucket,
    this.pageSize = 1000,
    this.pageToken,
  });

  /// Creates a [ListBuildersRequest] from JSON.
  static ListBuildersRequest fromJson(Map<String, dynamic> json) => _$ListBuildersRequestFromJson(json);

  /// LUCI project, e.g. "flutter".
  @JsonKey(required: true)
  final String project;

  /// A bucket in the project, e.g. "prod".
  ///
  /// Omit to list all builders or all builders in a project.
  @JsonKey(required: false)
  final String? bucket;

  /// The maximum number of builders to return.
  ///
  /// The service may return fewer than this value.
  /// If unspecified, at most 100 builders will be returned.
  /// The maximum value is 1000; values above 1000 will be coerced to 1000.
  @JsonKey(required: false)
  final int? pageSize;

  // A page token, received from a previous `ListBuilders` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListBuilders` MUST
  // match the call that provided the page token.
  @JsonKey(required: false)
  final String? pageToken;

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

  @override
  String toString() {
    return 'listBuilders(project: $project, bucket: $bucket, pageSize: $pageSize, pageToken: $pageToken)';
  }
}

/// The response object from a ListBuilders RPC.
@JsonSerializable(includeIfNull: false)
class ListBuildersResponse extends JsonBody {
  /// Creates a new response object from the ListBuilders RPC.
  ///
  /// The [nextPageToken] can be used to coninue searching if there are more
  /// builds available than the [pageSize] of the request (which is always
  /// capped at 1000). It will be null if no further builders are available.
  const ListBuildersResponse({
    this.builders,
    this.nextPageToken,
  });

  /// Creates a [ListBuildersResponse] from JSON.
  static ListBuildersResponse fromJson(Map<String, dynamic>? json) => _$ListBuildersResponseFromJson(json!);

  /// The [Builders]s returned by the search.
  final List<BuilderItem>? builders;

  /// A token that can be used as the [ListBuildersRequest.pageToken].
  ///
  /// This value will only be specified if further results are available;
  /// otherwise, it will be null.
  final String? nextPageToken;

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

  @override
  String toString() => builders.toString();
}

/// A request for the CancelBuild RPC.
@JsonSerializable(includeIfNull: false)
class CancelBuildRequest extends JsonBody {
  /// Creates a request object for the CancelBuild RPC.
  ///
  /// Both [id] and [summaryMarkdown] are required.
  const CancelBuildRequest({
    required this.id,
    required this.summaryMarkdown,
  });

  /// Creates a [CancelBuildRequest] from JSON.
  static CancelBuildRequest fromJson(Map<String, dynamic> json) => _$CancelBuildRequestFromJson(json);

  /// The BuildBucket ID for the build to cancel.
  @JsonKey(required: true)
  final String id;

  /// A summary of the reason for canceling.
  @JsonKey(required: true)
  final String summaryMarkdown;

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

  @override
  String toString() {
    return 'cancelBuild(id: $id, summaryMarkdown: $summaryMarkdown)';
  }
}

/// A request object for the SearchBuilds RPC.
@JsonSerializable(includeIfNull: false)
class SearchBuildsRequest extends JsonBody {
  /// Creates a request object for the SearchBuilds RPC.
  ///
  /// The [predicate] is required.
  ///
  /// The [pageSize] defaults to 100 if not specified.
  ///
  /// The [pageToken] from a previous request can be used to page through
  /// results.
  const SearchBuildsRequest({
    required this.predicate,
    this.pageSize,
    this.pageToken,
    this.fields,
  });

  /// Creates a [SearchBuildsReqeuest] object from JSON.
  static SearchBuildsRequest fromJson(Map<String, dynamic> json) => _$SearchBuildsRequestFromJson(json);

  /// The predicate for searching.
  final BuildPredicate predicate;

  /// The number of builds to return per request.  Defaults to 100.
  ///
  /// Any value over 1000 is treated as 1000.
  final int? pageSize;

  /// The value of the [SearchBuildsResponse.nextPageToken] from a previous ]
  /// request.
  ///
  /// This can be used to continue paging through results when there are more
  /// than [pageSize] builds available.
  final String? pageToken;

  /// The list fields to be included in the response.
  ///
  /// This is a comma separated list of Build proto fields to get included
  /// in the response.
  final String? fields;

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

  @override
  String toString() {
    return 'searchBuild(predicate: $predicate, pageSize: $pageSize, pageToken: $pageToken, fields: $fields)';
  }
}

/// A predicate to apply when searching for builds in the SearchBuilds RPC.
@JsonSerializable(includeIfNull: false)
class BuildPredicate extends JsonBody {
  /// Creates a predicate to apply when searching for builds in the SearchBuilds
  /// RPC.
  ///
  /// All items specified must match for the predicate to return.
  const BuildPredicate({
    this.builderId,
    this.status,
    this.createdBy,
    this.tags,
    this.includeExperimental,
  });

  /// Creates a [BuildPredicate] from JSON.
  static BuildPredicate fromJson(Map<String, dynamic> json) => _$BuildPredicateFromJson(json);

  /// The [BuilderId] to search for.
  @JsonKey(name: 'builder')
  final BuilderId? builderId;

  /// The [Status] to search for.
  final Status? status;

  /// Used to find builds created by the specified user.
  final String? createdBy;

  /// Used to return builds containing all of the specified tags.
  @TagsConverter()
  final Map<String?, List<String?>>? tags;

  /// Determines whether to include experimental builds in the result.
  ///
  /// Defaults to false.
  final bool? includeExperimental;

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

  @override
  String toString() {
    return 'buildPredicate(builderId: $builderId, status: $status, createdBy: $createdBy, tags: $tags, includeExperimental: $includeExperimental)';
  }
}

/// The response object from a SearchBuilds RPC.
@JsonSerializable(includeIfNull: false)
class SearchBuildsResponse extends JsonBody {
  /// Creates a new response object from the SearchBuilds RPC.
  ///
  /// The [nextPageToken] can be used to coninue searching if there are more
  /// builds available than the [pageSize] of the request (which is always
  /// capped at 1000). It will be null if no further builds are available.
  const SearchBuildsResponse({
    this.builds,
    this.nextPageToken,
  });

  /// Creates a [SearchBuildsResponse] from JSON.
  static SearchBuildsResponse fromJson(Map<String, dynamic>? json) => _$SearchBuildsResponseFromJson(json!);

  /// The [Build]s returned by the search.
  final List<Build>? builds;

  /// A token that can be used as the [SearchBuildsRequest.pageToken].
  ///
  /// This value will only be specified if further results are available;
  /// otherwise, it will be null.
  final String? nextPageToken;

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

  @override
  String toString() => builds.toString();
}

/// A request object for the ScheduleBuild RPC.
@JsonSerializable(includeIfNull: false)
class ScheduleBuildRequest extends JsonBody {
  /// Creates a new request object for the ScheduleBuild RPC.
  ///
  /// The [requestId] is "strongly recommended", and is used by the back end to
  /// deduplicate recent requests.
  ///
  /// The [builderId] is required.
  const ScheduleBuildRequest({
    this.requestId,
    required this.builderId,
    this.canary,
    this.experimental,
    this.gitilesCommit,
    this.properties,
    this.dimensions,
    this.priority,
    this.tags,
    this.notify,
    this.fields,
    this.exe,
  });

  /// Creates a [ScheduleBuildRequest] from JSON.
  static ScheduleBuildRequest fromJson(Map<String, dynamic> json) => _$ScheduleBuildRequestFromJson(json);

  /// A unique identifier per request that is used by the backend to deduplicate
  /// requests.
  ///
  /// This is "strongly recommended", but not required.
  final String? requestId;

  /// The [BuilderId] to schedule on. Required.
  @JsonKey(name: 'builder')
  final BuilderId builderId;

  /// If specified, overrides the server-defined value of
  /// Build.infra.buildbucket.canary.
  final bool? canary;

  /// If specified, overrides the server-defined value of
  /// Build.input.experimental.
  ///
  /// This value comes into the recipe as `api.runtime.is_experimental`.
  final Trinary? experimental;

  /// Properties to include in Build.input.properties.
  /// Input properties of the created build are result of merging server-defined
  /// properties and properties in this field.
  /// Each property in this field defines a new or replaces an existing property
  /// on the server.
  /// If the server config does not allow overriding/adding the property, the
  /// request will fail with InvalidArgument error code.
  /// A server-defined property cannot be removed, but its value can be
  /// replaced with null.
  ///
  /// Reserved property paths:
  /// * ["buildbucket"]
  /// * ["buildername"]
  /// * ["blamelist""]
  /// * ["$recipe_engine/runtime", "is_luci"]
  /// * ["$recipe_engine/runtime", "is_experimental"]
  final Map<String, Object>? properties;

  /// The value for Build.input.gitiles_commit.
  ///
  /// Setting this field will cause the created build to have a "buildset"
  /// tag with value "commit/gitiles/{hostname}/{project}/+/{id}".
  ///
  /// GitilesCommit objects MUST have host, project, ref fields set.
  final GitilesCommit? gitilesCommit;

  /// Tags to include in Build.tags of the created build.
  ///
  /// Note: tags of the created build may include other tags defined on the
  /// server.
  @TagsConverter()
  final Map<String?, List<String?>>? tags;

  /// Overrides default dimensions defined by builder config or template build.
  ///
  /// A set of entries with the same key defines a new or replaces an existing
  /// dimension with the same key.
  final List<RequestedDimension>? dimensions;

  // If not zero, overrides swarming task priority.
  // See also Build.infra.swarming.priority.
  final int? priority;

  /// The topic and user data to send build status updates to.
  final NotificationConfig? notify;

  /// The list fields to be included in the response.
  ///
  /// This is a comma separated list of Build proto fields to get included
  /// in the response.
  final String? fields;

  /// The CIPD package with the recipes.
  final Map<String, dynamic>? exe;

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

  @override
  String toString() {
    return 'scheduleBuildRequest(requestId: $requestId, builderId: $builderId, gitilesCommit: $gitilesCommit, fields: $fields, notify: $notify, exe: $exe)';
  }
}

/// A single build, identified by an int64 [id], belonging to a builder.
///
/// See also:
///   * [BuilderId]
///   * [GetBuildRequest]
@JsonSerializable(includeIfNull: false)
class Build extends JsonBody {
  /// Creates a build object.
  ///
  /// The [id] and [builderId] parameter is required.
  const Build({
    required this.id,
    required this.builderId,
    this.number,
    this.createdBy,
    this.canceledBy,
    this.startTime,
    this.endTime,
    this.status,
    this.tags,
    this.input,
    this.summaryMarkdown,
    this.critical,
  });

  /// Creates a [Build] object from JSON.
  static Build fromJson(Map<String, dynamic>? json) => _$BuildFromJson(json!);

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

  /// The [BuilderId] for the build.  Required.
  @JsonKey(name: 'builder')
  final BuilderId builderId;

  /// The LUCI build number for the build.
  ///
  /// This number corresponds to the order of builds, but build numbers may have
  /// gaps.
  final int? number;

  /// The verified LUCI identity that created the build.
  final String? createdBy;

  /// The verified LUCI identity that canceled the build.
  final String? canceledBy;

  /// The start time of the build.
  ///
  /// Required if and only if the [status] is [Status.started], [Status.success],
  /// or [Status.failure].
  final DateTime? startTime;

  /// The end time of the build.
  ///
  /// Required if and only if the [status] is terminal. Must not be before
  /// [startTime].
  final DateTime? endTime;

  /// The build status.
  ///
  /// Must be specified, and must not be [Status.unspecified].
  final Status? status;

  /// Human readable summary of the build in Markdown format.
  ///
  /// Up to 4kb.
  final String? summaryMarkdown;

  /// Arbitrary annotations for the build.
  ///
  /// The same key for a tag may be used multiple times.
  @TagsConverter()
  final Map<String?, List<String?>>? tags;

  /// If [Trinary.no], then the build status should not be used to assess the
  /// correctness of the input gitilesCommit or gerritChanges.
  final Trinary? critical;

  /// The build input values.
  final Input? input;

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

  @override
  String toString() => 'build(id: $id, builderId: $builderId, number: $number, status: $status, tags: $tags)';
}

/// A unique handle to a builder on BuildBucket.
@JsonSerializable(includeIfNull: false)
class BuilderId extends JsonBody {
  /// Creates a unique handle to a builder on BuildBucket.
  ///
  /// The bucket and builder control what ACLs for the infra, as specified in
  /// cr-buildbucket.cfg.
  const BuilderId({
    this.project,
    this.bucket,
    this.builder,
  });

  /// Creates a [BuilderId] object from JSON.
  static BuilderId fromJson(Map<String, dynamic> json) => _$BuilderIdFromJson(json);

  /// The project, e.g. "flutter", for the builder.
  final String? project;

  /// The bucket, e.g. "try" or "prod", for the builder.
  ///
  /// By convention, "prod" is for assets that will be released, "ci" is for
  /// reviewed code, and "try" is for untrusted code.
  final String? bucket;

  /// The builder from cr-buildbucket.cfg, e.g. "Linux" or "Linux Host Engine".
  final String? builder;

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

  @override
  String toString() => '$project/$bucket/$builder';

  @override
  bool operator ==(Object other) =>
      other is BuilderId && other.bucket == bucket && other.builder == builder && other.project == project;

  @override
  int get hashCode => toString().hashCode;
}

/// Specifies a Cloud PubSub topic to send notification updates to from a
/// [ScheduleBuildRequest].
@JsonSerializable(includeIfNull: false)
class NotificationConfig extends JsonBody {
  const NotificationConfig({this.pubsubTopic, this.userData});

  static NotificationConfig fromJson(Map<String, dynamic> json) => _$NotificationConfigFromJson(json);

  /// The Cloud PubSub topic to use, e.g.
  /// `projects/flutter-dashboard/topics/luci-builds`.
  final String? pubsubTopic;

  /// An optional user data field that will be delivered with the message.
  ///
  /// May be omitted.
  @Base64Converter()
  final String? userData;

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

  @override
  String toString() => 'NotificationConfig(pubsubTopic: $pubsubTopic, userData: $userData)';
}

/// The build inputs for a build.
@JsonSerializable(includeIfNull: false)
class Input extends JsonBody {
  /// Creates a set of build inputs for a build.
  const Input({
    this.properties,
    this.gitilesCommit,
    this.experimental,
  });

  /// Creates an [Input] object from JSON.
  static Input fromJson(Map<String, dynamic> json) => _$InputFromJson(json);

  /// The build properties of a build.
  final Map<String, Object>? properties;

  /// The [GitilesCommit] information for a build.
  final GitilesCommit? gitilesCommit;

  /// Whether the build is experimental or not. Passed into the recipe as
  /// `api.runtime.is_experimental`.
  final bool? experimental;

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

/// A landed Git commit hosted on Gitiles.
@JsonSerializable(includeIfNull: false)
class GitilesCommit extends JsonBody {
  /// Creates a object corresponding to a landed Git commit hosted on Gitiles.
  const GitilesCommit({
    this.host,
    this.project,
    this.ref,
    this.hash,
  });

  /// Creates a [GitilesCommit] object from JSON.
  static GitilesCommit fromJson(Map<String, dynamic> json) => _$GitilesCommitFromJson(json);

  /// The Gitiles host name, e.g. "chromium.googlesource.com"
  final String? host;

  /// The repository name on the host, e.g. "external/github.com/flutter/flutter".
  final String? project;

  /// The Git hash of the commit.
  @JsonKey(name: 'id')
  final String? hash;

  /// The Git ref of the commit, e.g. "refs/heads/master".
  final String? ref;

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

/// Build status values.
enum Status {
  /// Should not be used.
  @JsonValue('STATUS_UNSPECIFIED')
  unspecified,

  /// The status of a scheduled or pending build.
  @JsonValue('SCHEDULED')
  scheduled,

  /// The status of a started (running) build.
  @JsonValue('STARTED')
  started,

  /// A mask of `succes | failure | infraFailure | canceled`.
  @JsonValue('ENDED_MASK')
  ended,

  /// The build has successfully completed.
  @JsonValue('SUCCESS')
  success,

  /// The build has failed to complete some step due to a faulty test or commit.
  @JsonValue('FAILURE')
  failure,

  /// The build has failed due to an infrastructure related failure.
  @JsonValue('INFRA_FAILURE')
  infraFailure,

  /// The build was canceled.
  @JsonValue('CANCELED')
  canceled,
}

/// This type doesn't quite map to a bool, because there are actually four states
/// when you include whether it's present or not.
enum Trinary {
  /// A true value.
  @JsonValue('YES')
  yes,

  /// A false value.
  @JsonValue('NO')
  no,

  /// An explicit null value, which may or may not be treated differently from
  /// setting the JSON field to null.
  @JsonValue('UNSET')
  unset,
}

/// A requested dimension. Looks like StringPair, but also has an expiration.
@JsonSerializable(includeIfNull: false)
class RequestedDimension extends JsonBody {
  const RequestedDimension({
    required this.key,
    this.value,
    this.expiration,
  });

  static RequestedDimension fromJson(Map<String, dynamic> json) => _$RequestedDimensionFromJson(json);

  final String key;
  final String? value;

  /// If set, ignore this dimension after this duration. Must be a multiple of 1 minute. The format is '<seconds>s',
  /// e.g. '120s' represents 120 seconds.
  final String? expiration;

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