// Copyright 2020 The Jujutsu 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
//
// https://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";

package simple_op_store;

message RefConflictLegacy {
  repeated bytes removes = 1 [deprecated = true];
  repeated bytes adds = 2 [deprecated = true];
}

// This is redundant with `RefTargetTerm`. It exists for historical reasons.
// TODO: Consider deprecating it.
message RefConflict {
  message Term {
    optional bytes value = 1;
  }
  repeated Term removes = 1;
  repeated Term adds = 2;
}

// RefTarget that may be serialized in legacy form.
message RefTarget {
  // New `RefConflict` type represents both `commit_id` and `conflict_legacy`.
  oneof value {
    bytes commit_id = 1 [deprecated = true];
    RefConflictLegacy conflict_legacy = 2 [deprecated = true];
    RefConflict conflict = 3;
  }
}

// RefTarget term that should be serialized in native form, in which positive
// and negative terms alternate.
message RefTargetTerm {
  optional bytes value = 1;
}

enum RemoteRefState {
  New = 0;
  Tracked = 1;
}

message RemoteBookmark {
  string remote_name = 1;
  RefTarget target = 2;
  // Introduced in jj 0.11.
  optional RemoteRefState state = 3;
}

message Bookmark {
  string name = 1;
  // Unset if the bookmark has been deleted locally.
  RefTarget local_target = 2;
  // Deprecated since jj 0.34.
  repeated RemoteBookmark remote_bookmarks = 3 [deprecated = true];
}

message GitRef {
  string name = 1;
  // This field is just for historical reasons (before we had the RefTarget
  // type). New GitRefs have (only) the target field.
  // TODO: Delete support for the old format.
  bytes commit_id = 2 [deprecated = true];
  RefTarget target = 3;
}

message RemoteRef {
  string name = 1;
  repeated RefTargetTerm target_terms = 2;
  RemoteRefState state = 3;
}

message Tag {
  string name = 1;
  RefTarget target = 2;
}

message View {
  repeated bytes head_ids = 1;
  reserved 4;
  bytes wc_commit_id = 2 [deprecated = true];
  map<string, bytes> wc_commit_ids = 8;
  // Local bookmarks and remote bookmarks in legacy form.
  repeated Bookmark bookmarks = 5;
  repeated Tag local_tags = 6;
  // Introduced in jj 0.34.
  repeated RemoteView remote_views = 11;
  // Only a subset of the refs. For example, does not include refs/notes/.
  repeated GitRef git_refs = 3;
  // This field is just for historical reasons (before we had the RefTarget
  // type). New Views have (only) the target field.
  // TODO: Delete support for the old format.
  bytes git_head_legacy = 7 [deprecated = true];
  RefTarget git_head = 9;
  // Whether "@git" tags have been migrated to remote_views.
  bool has_git_refs_migrated_to_remote_tags = 12;
  reserved 10;
}

message RemoteView {
  string name = 1;
  repeated RemoteRef bookmarks = 2;
  repeated RemoteRef tags = 3;
}

message Operation {
  bytes view_id = 1;
  repeated bytes parents = 2;
  OperationMetadata metadata = 3;
  // Introduced in jj 0.30.
  repeated CommitPredecessors commit_predecessors = 4;
  // Whether or not `commit_predecessors` is recorded.
  bool stores_commit_predecessors = 5;
}

// TODO: Share with store.proto? Do we even need the timezone here?
message Timestamp {
  int64 millis_since_epoch = 1;
  int32 tz_offset = 2;
}

message OperationMetadata {
  Timestamp start_time = 1;
  Timestamp end_time = 2;
  string description = 3;
  string hostname = 4;
  string username = 5;
  bool is_snapshot = 7;
  optional string workspace_name = 8;
  map<string, string> attributes = 6;
}

message CommitPredecessors {
  bytes commit_id = 1;
  repeated bytes predecessor_ids = 2;
}
