// Copyright 2025 Google LLC
//
// 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";

package google.cloud.contentwarehouse.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/resource.proto";
import "google/cloud/contentwarehouse/v1/common.proto";
import "google/cloud/contentwarehouse/v1/document.proto";
import "google/cloud/contentwarehouse/v1/document_service_request.proto";
import "google/cloud/contentwarehouse/v1/histogram.proto";
import "google/cloud/contentwarehouse/v1/rule_engine.proto";
import "google/iam/v1/policy.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";

option csharp_namespace = "Google.Cloud.ContentWarehouse.V1";
option go_package = "cloud.google.com/go/contentwarehouse/apiv1/contentwarehousepb;contentwarehousepb";
option java_multiple_files = true;
option java_outer_classname = "DocumentServiceProto";
option java_package = "com.google.cloud.contentwarehouse.v1";
option php_namespace = "Google\\Cloud\\ContentWarehouse\\V1";
option ruby_package = "Google::Cloud::ContentWarehouse::V1";

// This service lets you manage document.
service DocumentService {
  option (google.api.default_host) = "contentwarehouse.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Creates a document.
  rpc CreateDocument(CreateDocumentRequest) returns (CreateDocumentResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/documents"
      body: "*"
    };
    option (google.api.method_signature) = "parent,document";
  }

  // Gets a document. Returns NOT_FOUND if the document does not exist.
  rpc GetDocument(GetDocumentRequest) returns (Document) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*/documents/*}:get"
      body: "*"
      additional_bindings {
        post: "/v1/{name=projects/*/locations/*/documents/referenceId/*}:get"
        body: "*"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a document. Returns INVALID_ARGUMENT if the name of the document
  // is non-empty and does not equal the existing name.
  rpc UpdateDocument(UpdateDocumentRequest) returns (UpdateDocumentResponse) {
    option (google.api.http) = {
      patch: "/v1/{name=projects/*/locations/*/documents/*}"
      body: "*"
      additional_bindings {
        patch: "/v1/{name=projects/*/locations/*/documents/referenceId/*}"
        body: "*"
      }
    };
    option (google.api.method_signature) = "name,document";
  }

  // Deletes a document. Returns NOT_FOUND if the document does not exist.
  rpc DeleteDocument(DeleteDocumentRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*/documents/*}:delete"
      body: "*"
      additional_bindings {
        post: "/v1/{name=projects/*/locations/*/documents/referenceId/*}:delete"
        body: "*"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Searches for documents using provided
  // [SearchDocumentsRequest][google.cloud.contentwarehouse.v1.SearchDocumentsRequest].
  // This call only returns documents that the caller has permission to search
  // against.
  rpc SearchDocuments(SearchDocumentsRequest)
      returns (SearchDocumentsResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/documents:search"
      body: "*"
    };
    option (google.api.method_signature) = "parent";
  }

  // Lock the document so the document cannot be updated by other users.
  rpc LockDocument(LockDocumentRequest) returns (Document) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*/documents/*}:lock"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }

  // Gets the access control policy for a resource. Returns NOT_FOUND error if
  // the resource does not exist. Returns an empty policy if the resource exists
  // but does not have a policy set.
  rpc FetchAcl(FetchAclRequest) returns (FetchAclResponse) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/locations/*/documents/*}:fetchAcl"
      body: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*}:fetchAcl"
        body: "*"
      }
    };
    option (google.api.method_signature) = "resource";
  }

  // Sets the access control policy for a resource. Replaces any existing
  // policy.
  rpc SetAcl(SetAclRequest) returns (SetAclResponse) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/locations/*/documents/*}:setAcl"
      body: "*"
      additional_bindings { post: "/v1/{resource=projects/*}:setAcl" body: "*" }
    };
    option (google.api.method_signature) = "resource,policy";
  }
}

// Response message for DocumentService.CreateDocument.
message CreateDocumentResponse {
  // Document created after executing create request.
  Document document = 1;

  // Output from Rule Engine recording the rule evaluator and action executor's
  // output.
  //
  // Refer format in: google/cloud/contentwarehouse/v1/rule_engine.proto
  RuleEngineOutput rule_engine_output = 2;

  // Additional information for the API invocation, such as the request tracking
  // id.
  ResponseMetadata metadata = 3;

  // post-processing LROs
  repeated google.longrunning.Operation long_running_operations = 4;
}

// Response message for DocumentService.UpdateDocument.
message UpdateDocumentResponse {
  // Updated document after executing update request.
  Document document = 1;

  // Output from Rule Engine recording the rule evaluator and action executor's
  // output.
  //
  // Refer format in: google/cloud/contentwarehouse/v1/rule_engine.proto
  RuleEngineOutput rule_engine_output = 2;

  // Additional information for the API invocation, such as the request tracking
  // id.
  ResponseMetadata metadata = 3;
}

// Additional result info for the question-answering feature.
message QAResult {
  // A text span in the search text snippet that represents a highlighted
  // section (answer context, highly relevant sentence, etc.).
  message Highlight {
    // Start index of the highlight.
    int32 start_index = 1;

    // End index of the highlight, exclusive.
    int32 end_index = 2;
  }

  // Highlighted sections in the snippet.
  repeated Highlight highlights = 1;

  // The calibrated confidence score for this document, in the range
  // [0., 1.]. This represents the confidence level for whether the returned
  // document and snippet answers the user's query.
  float confidence_score = 2;
}

// Response message for DocumentService.SearchDocuments.
message SearchDocumentsResponse {
  // Document entry with metadata inside
  // [SearchDocumentsResponse][google.cloud.contentwarehouse.v1.SearchDocumentsResponse]
  message MatchingDocument {
    // Document that matches the specified
    // [SearchDocumentsRequest][google.cloud.contentwarehouse.v1.SearchDocumentsRequest].
    // This document only contains indexed metadata information.
    Document document = 1;

    // Contains snippets of text from the document full raw text that most
    // closely match a search query's keywords, if available. All HTML tags in
    // the original fields are stripped when returned in this field, and
    // matching query keywords are enclosed in HTML bold tags.
    //
    // If the question-answering feature is enabled, this field will instead
    // contain a snippet that answers the user's natural-language query. No HTML
    // bold tags will be present, and highlights in the answer snippet can be
    // found in
    // [QAResult.highlights][google.cloud.contentwarehouse.v1.QAResult.highlights].
    string search_text_snippet = 2;

    // Experimental.
    // Additional result info if the question-answering feature is enabled.
    QAResult qa_result = 3;

    // Return the 1-based page indices where those pages have one or more
    // matched tokens.
    repeated int64 matched_token_page_indices = 4;
  }

  // The document entities that match the specified
  // [SearchDocumentsRequest][google.cloud.contentwarehouse.v1.SearchDocumentsRequest].
  repeated MatchingDocument matching_documents = 1;

  // The token that specifies the starting position of the next page of results.
  // This field is empty if there are no more results.
  string next_page_token = 2;

  // The total number of matched documents which is available only if the client
  // set
  // [SearchDocumentsRequest.require_total_size][google.cloud.contentwarehouse.v1.SearchDocumentsRequest.require_total_size]
  // to `true` or set
  // [SearchDocumentsRequest.total_result_size][google.cloud.contentwarehouse.v1.SearchDocumentsRequest.total_result_size]
  // to `ESTIMATED_SIZE` or `ACTUAL_SIZE`. Otherwise, the value will be `-1`.
  // Typically a UI would handle this condition by displaying &quot;of
  // many&quot;, for example: &quot;Displaying 10 of many&quot;.
  int32 total_size = 3;

  // Additional information for the API invocation, such as the request tracking
  // id.
  ResponseMetadata metadata = 4;

  // The histogram results that match with the specified
  // [SearchDocumentsRequest.histogram_queries][google.cloud.contentwarehouse.v1.SearchDocumentsRequest.histogram_queries].
  repeated HistogramQueryResult histogram_query_results = 6;

  // Experimental.
  // Question answer from the query against the document.
  string question_answer = 7;
}

// Response message for DocumentService.FetchAcl.
message FetchAclResponse {
  // The IAM policy.
  google.iam.v1.Policy policy = 1;

  // Additional information for the API invocation, such as the request tracking
  // id.
  ResponseMetadata metadata = 2;
}

// Response message for DocumentService.SetAcl.
message SetAclResponse {
  // The policy will be attached to a resource (e.g. projecct, document).
  google.iam.v1.Policy policy = 1;

  // Additional information for the API invocation, such as the request tracking
  // id.
  ResponseMetadata metadata = 2;
}
