// Copyright 2017 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

option go_package = "go.chromium.org/luci/common/proto/gitiles";

package gitiles;

import "go.chromium.org/luci/common/proto/git/commit.proto";

service Gitiles {
    // Log retrieves commit log.
    rpc Log(LogRequest) returns (LogResponse) {};
    // Refs retrieves repo refs.
    rpc Refs(RefsRequest) returns (RefsResponse) {};
    // Archive retrieves archived contents of the project.
    //
    // An archive is a shallow bundle of the contents of a repository.
    //
    // DEPRECATED: Use DownloadFile to obtain plain text files.
    // TODO(pprabhu): Migrate known users to DownloadFile and delete this RPC.
    rpc Archive(ArchiveRequest) returns (ArchiveResponse) {};
    // DownloadFile retrieves a file from the project.
    rpc DownloadFile(DownloadFileRequest) returns (DownloadFileResponse) {};
    // Projects retrieves list of available Gitiles projects
    rpc Projects(ProjectsRequest) returns (ProjectsResponse) {};
}

// LogRequest is request message for Gitiles.Log rpc.
message LogRequest {
    // Gitiles project, e.g. "chromium/src" part in
    // https://chromium.googlesource.com/chromium/src/+/master
    // Required.
    string project = 1;
    // The commit where to start the listing from.
    // The value can be:
    //   - a git revision as 40-char string or its prefix so long as its unique in repo.
    //   - a ref such as "refs/heads/branch"
    //   - a ref defined as n-th parent of R in the form "R~n".
    //     For example, "master~2" or "deadbeef~1".
    // Required.
    string committish = 3;
    // If specified, only commits not reachable from this commit (inclusive)
    // will be returned.
    //
    // In git's notation, this is
    //   $ git log ^exclude_ancestors_of committish
    //  OR
    //   $ git log exclude_ancestors_of..committish
    // https://git-scm.com/docs/gitrevisions#gitrevisions-Theememtwo-dotRangeNotation
    //
    // For example, given this repo
    //
    //     base -> A -> B -> C == refs/heads/master
    //        \
    //         X -> Y -> Z  == refs/heads/release
    //
    // calling Log(committish='refs/heads/release',
    //             exclude_ancestors_of='refs/heads/master')
    // will return ['Z', Y', 'X'].
    string exclude_ancestors_of = 2;
    // If true, include tree diff in commits.
    bool tree_diff = 4;

    // Value of next_page_token in LogResponse to continue.
    string page_token = 10;
    // If > 0, number of commits to retrieve.
    int32 page_size = 11;
}

// LogRequest is response message for Gitiles.Log rpc.
message LogResponse {
    // Retrieved commits.
    repeated git.Commit log = 1;
    // A page token for next LogRequest to fetch next page of commits.
    string next_page_token = 2;
}

// RefsRequest is a request message of Gitiles.Refs RPC.
message RefsRequest {
    // Gitiles project, e.g. "chromium/src" part in
    // https://chromium.googlesource.com/chromium/src/+/master
    // Required.
    string project = 1;
    // Limits which refs to resolve to only those matching {refsPath}/*.
    //
    // Must be "refs" or start with "refs/".
    // Must not include glob '*'.
    // Use "refs/heads" to retrieve all branches.
    //
    // To fetch **all** refs in a repo, specify just "refs" but beware of two
    // caveats:
    //  * refs returned include a ref for each patchset for each Gerrit change
    //    associated with the repo.
    //  * returned map will contain special "HEAD" ref whose value in resulting map
    //    will be name of the actual ref to which "HEAD" points, which is typically
    //    "refs/heads/master".
    //
    // Thus, if you are looking for all tags and all branches of repo, it's
    // recommended to issue two Refs calls limited to "refs/tags" and "refs/heads"
    // instead of one call for "refs".
    //
    // Since Gerrit allows per-ref ACLs, it is possible that some refs matching
    // refPrefix would not be present in results because current user isn't granted
    // read permission on them.
    string refs_path = 2;
}

// RefsResponse is a response message of Gitiles.Refs RPC.
message RefsResponse {
    // revisions maps a ref to a revision.
    // Git branches have keys start with "refs/heads/".
    map<string, string> revisions = 2;
}

// ArchiveRequest is a request message of the Gitiles.Archive RPC.
message ArchiveRequest {
    // Gitiles project, e.g. "chromium/src" part in
    // https://chromium.googlesource.com/chromium/src/+/master
    // Required.
    string project = 1;

    // The ref at which to generate the project archive for.
    //
    // viz refs/for/branch or just branch
    string ref = 2;

    // List copied from
    // https://github.com/google/gitiles/blob/65edbe49f2b3882a5979f602383ef0c7b2b8ee0c/java/com/google/gitiles/ArchiveFormat.java
    enum Format {
        Invalid = 0;
        GZIP = 1;
        TAR = 2;
        BZIP2 = 3;
        XZ = 4;
    }
    // Format of the returned project archive.
    Format format = 3;
}

message ArchiveResponse {
    // Suggested name of the returned archive.
    string filename = 1;

    // Contents of the archive streamed from gitiles.
    //
    // The underlying server RPC streams back the contents. This API simplifies
    // the RPC to a non-streaming response.
    bytes contents = 2;
}

message DownloadFileRequest {
    // Gitiles project, e.g. "chromium/src" part in
    // https://chromium.googlesource.com/chromium/src/+/master
    // Required.
    string project = 1;

    // The commit where to start the listing from.
    // The value can be:
    //   - a git revision as 40-char string or its prefix so long as its unique in repo.
    //   - a ref such as "refs/heads/branch"
    //   - a ref defined as n-th parent of R in the form "R~n".
    //     For example, "master~2" or "deadbeef~1".
    // Required.
    string committish = 2;

    // Path relative to the project root to the file to download.
    string path = 3;

    enum Format {
        FormatInvalid = 0;
        TEXT = 1;
    }
    // Format to download file in.
    Format format = 4;
}

message DownloadFileResponse {
    // Decoded contents of the downloaded file.
    //
    // The underlying server RPC streams back the contents. This API simplifies
    // the RPC to a non-streaming response.
    string contents = 1;
}

message ProjectsRequest {
}

message ProjectsResponse {
    // List of available Gitiles projects
  repeated string projects = 1;
}
