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

// https://developers.google.com/protocol-buffers/docs/proto3
syntax = "proto3";

package apipb;

message HasAncestorRequest {
  string commit = 1;   // full git commit hash (subject of query)
  string ancestor = 2; // full git commit hash of sought ancestor
}

message HasAncestorResponse {
  // has_ancestor is whether ancestor appears in commit's history.
  bool has_ancestor = 1;

  // unknown_commit is true if the provided commit was unknown.
  bool unknown_commit = 2;
}


message GetRefRequest {
  string ref = 1;  // "HEAD", "refs/heads/master", etc.

  // Either gerrit_server & gerrit_project must be specified, or
  // github. Currently only Gerrit is supported.
  string gerrit_server = 2;   // "go.googlesource.com"
  string gerrit_project = 3;  // "go"

  // TODO: github, if/when needed.
}

message GetRefResponse {
  string value = 1; // git commit, or empty string on miss
}

message GoFindTryWorkRequest {
  // for_staging says whether this is a trybot request for the staging
  // cluster. When using staging, the comment "Run-StagingTryBot"
  // is used instead of label:Run-TryBot=1.
  bool for_staging = 1;
}

message GoFindTryWorkResponse {
  // waiting are the Gerrit CLs wanting a trybot run and not yet with results.
  // These might already be running.
  repeated GerritTryWorkItem waiting = 1;
}

message GerritTryWorkItem {
  string project = 1;    // "go", "net", etc. (Gerrit Project)
  string branch = 2;     // "master", "release-branch.go1.8", etc.
  string change_id = 3;  // "I1a27695838409259d1586a0adfa9f92bccf7ceba"
  string commit = 4;     // "ecf3dffc81dc21408fb02159af352651882a8383"

  int32 version = 9; // which Gerrit revision number commit is

  // go_commit is set for subrepos and is the Go commit(s) to test against.
  // go_branch is a branch name of go_commit, for showing to users when
  // a try set fails.
  repeated string go_commit = 5;  // "4833e920c1d7f6b23458e6ff3c73951fcf754219"
  repeated string go_branch = 6;  // "master", "release-branch.go1.8", etc.

  // go_version specifies the major and minor version of the targeted Go toolchain.
  // For Go repo, it contains exactly one element.
  // For subrepos, it contains elements that correspond to go_commit.
  repeated MajorMinor go_version = 7;

  // try_message is the list of TRY=xxxx messages associated with Run-TryBot votes.
  // It's sorted from oldest to newest.
  repeated TryVoteMessage try_message = 8;
}

message TryVoteMessage {
  string message = 1;   // just the part after "TRY=" until end of line, without \n
  int64  author_id = 2; // Gerrit-internal ID
  int32  version = 3;   // revision number comment was for
}

message MajorMinor {
  int32 major = 1;
  int32 minor = 2;
}

message ListGoReleasesRequest {}

message ListGoReleasesResponse {
  repeated GoRelease releases = 1;
}

message GoRelease {
  int32 major = 1;
  int32 minor = 2;
  int32 patch = 3;
  string tag_name = 4;       // "go1.11.1", etc.
  string tag_commit = 5;     // "26957168c4c0cdcc7ca4f0b19d0eb19474d224ac"

  // Release branch information for this major-minor version pair.
  string branch_name = 6;    // "release-branch.go1.11", etc.
  string branch_commit = 7;  // most recent commit on the release branch, e.g., "edb6c16b9b62ed8586d2e3e422911d646095b7e5"
}

message DashboardRequest {
  // page is the zero-based page number.
  // TODO: deprecate, replace with time or commit continuation token.
  int32 page = 1;

  // repo is which repo to show ("go", "golang.org/x/net", "" means go).
  string repo = 2;

  // branch specifies which branch to show ("master", "release-branch.go1.13").
  // Empty means "master".
  // The special branch value "mixed" means to blend together all branches by commit time.
  string branch = 3;

  // max_commits specifies the number of commits that are desired.
  // Zero means to use a default.
  int32 max_commits = 4;
}

message DashboardResponse {
  // commits are the commits to display, starting with the newest.
  repeated DashCommit commits = 1;

  // commits_truncated is whether the returned commits were truncated.
  bool commits_truncated = 5;

  // repo_heads contains the current head commit (of their master
  // branch) for every repo on Go's Gerrit server.
  repeated DashRepoHead repo_heads = 2;

  repeated string branches = 3;

  // releases is the same content is ListGoReleasesResponse, but with the addition of a "master"
  // release first, containing the info for the "master" branch, which is just commits[0]
  // if page 0. But if page != 0, the master head wouldn't be
  // available otherwise, so we denormalize it a bit here:
  // It's sorted from newest to oldest (master, release-branch.go1.latest, release-branch.go1.prior)
  // Only the branch_name and branch_commit fields are guaranteed to be populated.
  repeated GoRelease releases = 4;
}

message DashCommit {
  // commit is the git commit hash ("26957168c4c0cdcc7ca4f0b19d0eb19474d224ac").
  string commit = 1;

  // author_name is the git author name part ("Foo Bar").
  string author_name = 2;     // "Foo Bar"

  // author_email is the git author email part ("foo@bar.com").
  string author_email = 3;    // "foo@bar.com"

  // commit_time_sec is the timestamp of git commit time, in unix seconds.
  int64 commit_time_sec = 4;

  // title is the git commit's first line ("runtime: fix all the bugs").
  string title = 5;

  // branch is the branch this commit was queried from ("master", "release-branch.go1.14")/
  // This is normally redundant but is useful when DashboardRequest.branch == "mixed".
  string branch = 7;

  // For non-go repos, go_commit_at_time is what the Go master commit was at
  // the time of DashCommit.commit_time.
  string go_commit_at_time = 6;

  // For non-go repos, go_commit_latest is the most recent Go master commit that's
  // older than the the following x/foo commit's commit_time.
  // If DashCommit is the current HEAD, go_commit_at_time can continue to update.
  // go_commit_at_time might be the same as go_commit_at_time.
  string go_commit_latest = 8;
}

message DashRepoHead {
  // gerrit_project is Gerrit project name ("net", "go").
  string gerrit_project = 1;

  // commit is the current top-level commit in that project.
  // (currently always on the master branch)
  DashCommit commit = 2;
}

service MaintnerService {
  // HasAncestor reports whether one commit contains another commit
  // in its git history.
  rpc HasAncestor(HasAncestorRequest) returns (HasAncestorResponse);

  // GetRef returns information about a git ref.
  rpc GetRef(GetRefRequest) returns (GetRefResponse);

  // Go-specific methods:

  // GoFindTryWork finds trybot work for the coordinator to build & test.
  rpc GoFindTryWork(GoFindTryWorkRequest) returns (GoFindTryWorkResponse);

  // ListGoReleases lists Go releases sorted by version with latest first.
  //
  // A release is considered to exist for each git tag named "goX", "goX.Y", or
  // "goX.Y.Z", as long as it has a corresponding "release-branch.goX" or
  // "release-branch.goX.Y" release branch.
  //
  // ListGoReleases returns only the latest patch versions of releases which
  // are considered supported per policy. For example, Go 1.12.6 and 1.11.11.
  // The response is guaranteed to have two versions, otherwise an error
  // is returned.
  rpc ListGoReleases(ListGoReleasesRequest) returns (ListGoReleasesResponse);

  // GetDashboard returns the information for the build.golang.org
  // dashboard. It does not (at least currently)
  // contain any pass/fail information; it only contains information on the branches
  // and commits themselves.
  rpc GetDashboard(DashboardRequest) returns (DashboardResponse);
}
