// Copyright 2021 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.dialogflow.cx.v3beta1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/dialogflow/cx/v3beta1/advanced_settings.proto";
import "google/cloud/dialogflow/cx/v3beta1/fulfillment.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";

option cc_enable_arenas = true;
option csharp_namespace = "Google.Cloud.Dialogflow.Cx.V3Beta1";
option go_package = "google.golang.org/genproto/googleapis/cloud/dialogflow/cx/v3beta1;cx";
option java_multiple_files = true;
option java_outer_classname = "PageProto";
option java_package = "com.google.cloud.dialogflow.cx.v3beta1";
option objc_class_prefix = "DF";

// Service for managing [Pages][google.cloud.dialogflow.cx.v3beta1.Page].
service Pages {
  option (google.api.default_host) = "dialogflow.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform,"
      "https://www.googleapis.com/auth/dialogflow";

  // Returns the list of all pages in the specified flow.
  rpc ListPages(ListPagesRequest) returns (ListPagesResponse) {
    option (google.api.http) = {
      get: "/v3beta1/{parent=projects/*/locations/*/agents/*/flows/*}/pages"
    };
    option (google.api.method_signature) = "parent";
  }

  // Retrieves the specified page.
  rpc GetPage(GetPageRequest) returns (Page) {
    option (google.api.http) = {
      get: "/v3beta1/{name=projects/*/locations/*/agents/*/flows/*/pages/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a page in the specified flow.
  rpc CreatePage(CreatePageRequest) returns (Page) {
    option (google.api.http) = {
      post: "/v3beta1/{parent=projects/*/locations/*/agents/*/flows/*}/pages"
      body: "page"
    };
    option (google.api.method_signature) = "parent,page";
  }

  // Updates the specified page.
  rpc UpdatePage(UpdatePageRequest) returns (Page) {
    option (google.api.http) = {
      patch: "/v3beta1/{page.name=projects/*/locations/*/agents/*/flows/*/pages/*}"
      body: "page"
    };
    option (google.api.method_signature) = "page,update_mask";
  }

  // Deletes the specified page.
  rpc DeletePage(DeletePageRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v3beta1/{name=projects/*/locations/*/agents/*/flows/*/pages/*}"
    };
    option (google.api.method_signature) = "name";
  }
}

// A Dialogflow CX conversation (session) can be described and visualized as a
// state machine. The states of a CX session are represented by pages.
//
// For each flow, you define many pages, where your combined pages can handle a
// complete conversation on the topics the flow is designed for. At any given
// moment, exactly one page is the current page, the current page is considered
// active, and the flow associated with that page is considered active. Every
// flow has a special start page. When a flow initially becomes active, the
// start page page becomes the current page. For each conversational turn, the
// current page will either stay the same or transition to another page.
//
// You configure each page to collect information from the end-user that is
// relevant for the conversational state represented by the page.
//
// For more information, see the
// [Page guide](https://cloud.google.com/dialogflow/cx/docs/concept/page).
message Page {
  option (google.api.resource) = {
    type: "dialogflow.googleapis.com/Page"
    pattern: "projects/{project}/locations/{location}/agents/{agent}/flows/{flow}/pages/{page}"
  };

  // The unique identifier of the page.
  // Required for the [Pages.UpdatePage][google.cloud.dialogflow.cx.v3beta1.Pages.UpdatePage] method. [Pages.CreatePage][google.cloud.dialogflow.cx.v3beta1.Pages.CreatePage]
  // populates the name automatically.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>/pages/<Page ID>`.
  string name = 1;

  // Required. The human-readable name of the page, unique within the agent.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // The fulfillment to call when the session is entering the page.
  Fulfillment entry_fulfillment = 7;

  // The form associated with the page, used for collecting parameters
  // relevant to the page.
  Form form = 4;

  // Ordered list of [`TransitionRouteGroups`][google.cloud.dialogflow.cx.v3beta1.TransitionRouteGroup] associated
  // with the page. Transition route groups must be unique within a page.
  //
  // *   If multiple transition routes within a page scope refer to the same
  //     intent, then the precedence order is: page's transition route -> page's
  //     transition route group -> flow's transition routes.
  //
  // *   If multiple transition route groups within a page contain the same
  //     intent, then the first group in the ordered list takes precedence.
  //
  // Format:`projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>/transitionRouteGroups/<TransitionRouteGroup ID>`.
  repeated string transition_route_groups = 11 [(google.api.resource_reference) = {
                                                  type: "dialogflow.googleapis.com/TransitionRouteGroup"
                                                }];

  // A list of transitions for the transition rules of this page.
  // They route the conversation to another page in the same flow, or another
  // flow.
  //
  // When we are in a certain page, the TransitionRoutes are evalauted in the
  // following order:
  //
  // *   TransitionRoutes defined in the page with intent specified.
  // *   TransitionRoutes defined in the
  //     [transition route groups][google.cloud.dialogflow.cx.v3beta1.Page.transition_route_groups] with intent
  //     specified.
  // *   TransitionRoutes defined in flow with intent specified.
  // *   TransitionRoutes defined in the
  //     [transition route groups][google.cloud.dialogflow.cx.v3beta1.Flow.transition_route_groups] with intent
  //     specified.
  // *   TransitionRoutes defined in the page with only condition specified.
  // *   TransitionRoutes defined in the
  //     [transition route groups][google.cloud.dialogflow.cx.v3beta1.Page.transition_route_groups] with only
  //     condition specified.
  repeated TransitionRoute transition_routes = 9;

  // Handlers associated with the page to handle events such as webhook errors,
  // no match or no input.
  repeated EventHandler event_handlers = 10;
}

// A form is a data model that groups related parameters that can be collected
// from the user. The process in which the agent prompts the user and collects
// parameter values from the user is called form filling. A form can be added to
// a [page][google.cloud.dialogflow.cx.v3beta1.Page]. When form filling is done, the filled parameters will be
// written to the [session][google.cloud.dialogflow.cx.v3beta1.SessionInfo.parameters].
message Form {
  // Represents a form parameter.
  message Parameter {
    // Configuration for how the filling of a parameter should be handled.
    message FillBehavior {
      // Required. The fulfillment to provide the initial prompt that the agent
      // can present to the user in order to fill the parameter.
      Fulfillment initial_prompt_fulfillment = 3 [(google.api.field_behavior) = REQUIRED];

      // The handlers for parameter-level events, used to provide reprompt for
      // the parameter or transition to a different page/flow. The supported
      // events are:
      // *   `sys.no-match-<N>`, where N can be from 1 to 6
      // *   `sys.no-match-default`
      // *   `sys.no-input-<N>`, where N can be from 1 to 6
      // *   `sys.no-input-default`
      // *   `sys.invalid-parameter`
      //
      // `initial_prompt_fulfillment` provides the first prompt for the
      // parameter.
      //
      // If the user's response does not fill the parameter, a
      // no-match/no-input event will be triggered, and the fulfillment
      // associated with the `sys.no-match-1`/`sys.no-input-1` handler (if
      // defined) will be called to provide a prompt. The
      // `sys.no-match-2`/`sys.no-input-2` handler (if defined) will respond to
      // the next no-match/no-input event, and so on.
      //
      // A `sys.no-match-default` or `sys.no-input-default` handler will be used
      // to handle all following no-match/no-input events after all numbered
      // no-match/no-input handlers for the parameter are consumed.
      //
      // A `sys.invalid-parameter` handler can be defined to handle the case
      // where the parameter values have been `invalidated` by webhook. For
      // example, if the user's response fill the parameter, however the
      // parameter was invalidated by webhook, the fulfillment associated with
      // the `sys.invalid-parameter` handler (if defined) will be called to
      // provide a prompt.
      //
      // If the event handler for the corresponding event can't be found on the
      // parameter, `initial_prompt_fulfillment` will be re-prompted.
      repeated EventHandler reprompt_event_handlers = 5;
    }

    // Required. The human-readable name of the parameter, unique within the
    // form.
    string display_name = 1 [(google.api.field_behavior) = REQUIRED];

    // Indicates whether the parameter is required. Optional parameters will not
    // trigger prompts; however, they are filled if the user specifies them.
    // Required parameters must be filled before form filling concludes.
    bool required = 2;

    // Required. The entity type of the parameter.
    // Format: `projects/-/locations/-/agents/-/entityTypes/<System Entity Type
    // ID>` for system entity types (for example,
    // `projects/-/locations/-/agents/-/entityTypes/sys.date`), or
    // `projects/<Project ID>/locations/<Location ID>/agents/<Agent
    // ID>/entityTypes/<Entity Type ID>` for developer entity types.
    string entity_type = 3 [
      (google.api.field_behavior) = REQUIRED,
      (google.api.resource_reference) = {
        type: "dialogflow.googleapis.com/EntityType"
      }
    ];

    // Indicates whether the parameter represents a list of values.
    bool is_list = 4;

    // Required. Defines fill behavior for the parameter.
    FillBehavior fill_behavior = 7 [(google.api.field_behavior) = REQUIRED];

    // The default value of an optional parameter. If the parameter is required,
    // the default value will be ignored.
    google.protobuf.Value default_value = 9;

    // Indicates whether the parameter content should be redacted in log.  If
    // redaction is enabled, the parameter content will be replaced by parameter
    // name during logging.
    // Note: the parameter content is subject to redaction if either parameter
    // level redaction or [entity type level redaction][google.cloud.dialogflow.cx.v3beta1.EntityType.redact] is
    // enabled.
    bool redact = 11;
  }

  // Parameters to collect from the user.
  repeated Parameter parameters = 1;
}

// An event handler specifies an [event][google.cloud.dialogflow.cx.v3beta1.EventHandler.event] that can be handled
// during a session. When the specified event happens, the following actions are
// taken in order:
//
// *   If there is a
// [`trigger_fulfillment`][google.cloud.dialogflow.cx.v3beta1.EventHandler.trigger_fulfillment] associated with
// the event, it will be called.
// *   If there is a [`target_page`][google.cloud.dialogflow.cx.v3beta1.EventHandler.target_page] associated
// with the event, the session will transition into the specified page.
// *   If there is a [`target_flow`][google.cloud.dialogflow.cx.v3beta1.EventHandler.target_flow] associated
// with the event, the session will transition into the specified flow.
message EventHandler {
  // Output only. The unique identifier of this event handler.
  string name = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The name of the event to handle.
  string event = 4 [(google.api.field_behavior) = REQUIRED];

  // The fulfillment to call when the event occurs.
  // Handling webhook errors with a fulfillment enabled with webhook could
  // cause infinite loop. It is invalid to specify such fulfillment for a
  // handler handling webhooks.
  Fulfillment trigger_fulfillment = 5;

  // The target to transition to, either a page in the same host flow (the flow
  // that owns this [TransitionRoute][google.cloud.dialogflow.cx.v3beta1.TransitionRoute]), or another flow in the same agent.
  oneof target {
    // The target page to transition to.
    // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
    // ID>/flows/<Flow ID>/pages/<Page ID>`.
    string target_page = 2 [(google.api.resource_reference) = {
                              type: "dialogflow.googleapis.com/Page"
                            }];

    // The target flow to transition to.
    // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
    // ID>/flows/<Flow ID>`.
    string target_flow = 3 [(google.api.resource_reference) = {
                              type: "dialogflow.googleapis.com/Flow"
                            }];
  }
}

// A transition route specifies a [intent][google.cloud.dialogflow.cx.v3beta1.Intent] that can be matched and/or a
// data condition that can be evaluated during a session. When a specified
// transition is matched, the following actions are taken in order:
//
// *   If there is a
// [`trigger_fulfillment`][google.cloud.dialogflow.cx.v3beta1.TransitionRoute.trigger_fulfillment] associated with
// the transition, it will be called.
// *   If there is a [`target_page`][google.cloud.dialogflow.cx.v3beta1.TransitionRoute.target_page] associated
// with the transition, the session will transition into the specified page.
// *   If there is a [`target_flow`][google.cloud.dialogflow.cx.v3beta1.TransitionRoute.target_flow] associated
// with the transition, the session will transition into the specified flow.
message TransitionRoute {
  // Output only. The unique identifier of this transition route.
  string name = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The unique identifier of an [Intent][google.cloud.dialogflow.cx.v3beta1.Intent].
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/intents/<Intent ID>`.
  // Indicates that the transition can only happen when the given intent is
  // matched.
  // At least one of `intent` or `condition` must be specified. When both
  // `intent` and `condition` are specified, the transition can only happen
  // when both are fulfilled.
  string intent = 1 [(google.api.resource_reference) = {
                       type: "dialogflow.googleapis.com/Intent"
                     }];

  // The condition to evaluate against [form parameters][google.cloud.dialogflow.cx.v3beta1.Form.parameters] or
  // [session parameters][google.cloud.dialogflow.cx.v3beta1.SessionInfo.parameters].
  //
  // See the [conditions
  // reference](https://cloud.google.com/dialogflow/cx/docs/reference/condition).
  // At least one of `intent` or `condition` must be specified. When both
  // `intent` and `condition` are specified, the transition can only happen
  // when both are fulfilled.
  string condition = 2;

  // The fulfillment to call when the condition is satisfied. At least one of
  // `trigger_fulfillment` and `target` must be specified. When both are
  // defined, `trigger_fulfillment` is executed first.
  Fulfillment trigger_fulfillment = 3;

  // The target to transition to, either a page in the same host flow (the flow
  // that owns this [TransitionRoute][google.cloud.dialogflow.cx.v3beta1.TransitionRoute]), or another flow in the same agent.
  oneof target {
    // The target page to transition to.
    // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
    // ID>/flows/<Flow ID>/pages/<Page ID>`.
    string target_page = 4 [(google.api.resource_reference) = {
                              type: "dialogflow.googleapis.com/Page"
                            }];

    // The target flow to transition to.
    // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
    // ID>/flows/<Flow ID>`.
    string target_flow = 5 [(google.api.resource_reference) = {
                              type: "dialogflow.googleapis.com/Flow"
                            }];
  }
}

// The request message for [Pages.ListPages][google.cloud.dialogflow.cx.v3beta1.Pages.ListPages].
message ListPagesRequest {
  // Required. The flow to list all pages for.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dialogflow.googleapis.com/Page"
    }
  ];

  // The language to list pages for. The following fields are language
  // dependent:
  //
  // *  `Page.entry_fulfillment.messages`
  // *  `Page.entry_fulfillment.conditional_cases`
  // *  `Page.event_handlers.trigger_fulfillment.messages`
  // *  `Page.event_handlers.trigger_fulfillment.conditional_cases`
  // *  `Page.form.parameters.fill_behavior.initial_prompt_fulfillment.messages`
  // *
  // `Page.form.parameters.fill_behavior.initial_prompt_fulfillment.conditional_cases`
  // *  `Page.form.parameters.fill_behavior.reprompt_event_handlers.messages`
  // *
  // `Page.form.parameters.fill_behavior.reprompt_event_handlers.conditional_cases`
  // *  `Page.transition_routes.trigger_fulfillment.messages`
  // *  `Page.transition_routes.trigger_fulfillment.conditional_cases`
  //
  // If not specified, the agent's default language is used.
  // [Many
  // languages](https://cloud.google.com/dialogflow/cx/docs/reference/language)
  // are supported.
  // Note: languages must be enabled in the agent before they can be used.
  string language_code = 2;

  // The maximum number of items to return in a single page. By default 100 and
  // at most 1000.
  int32 page_size = 3;

  // The next_page_token value returned from a previous list request.
  string page_token = 4;
}

// The response message for [Pages.ListPages][google.cloud.dialogflow.cx.v3beta1.Pages.ListPages].
message ListPagesResponse {
  // The list of pages. There will be a maximum number of items returned based
  // on the page_size field in the request.
  repeated Page pages = 1;

  // Token to retrieve the next page of results, or empty if there are no more
  // results in the list.
  string next_page_token = 2;
}

// The request message for [Pages.GetPage][google.cloud.dialogflow.cx.v3beta1.Pages.GetPage].
message GetPageRequest {
  // Required. The name of the page.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>/pages/<Page ID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Page"
    }
  ];

  // The language to retrieve the page for. The following fields are language
  // dependent:
  //
  // *  `Page.entry_fulfillment.messages`
  // *  `Page.entry_fulfillment.conditional_cases`
  // *  `Page.event_handlers.trigger_fulfillment.messages`
  // *  `Page.event_handlers.trigger_fulfillment.conditional_cases`
  // *  `Page.form.parameters.fill_behavior.initial_prompt_fulfillment.messages`
  // *
  // `Page.form.parameters.fill_behavior.initial_prompt_fulfillment.conditional_cases`
  // *  `Page.form.parameters.fill_behavior.reprompt_event_handlers.messages`
  // *
  // `Page.form.parameters.fill_behavior.reprompt_event_handlers.conditional_cases`
  // *  `Page.transition_routes.trigger_fulfillment.messages`
  // *  `Page.transition_routes.trigger_fulfillment.conditional_cases`
  //
  // If not specified, the agent's default language is used.
  // [Many
  // languages](https://cloud.google.com/dialogflow/cx/docs/reference/language)
  // are supported.
  // Note: languages must be enabled in the agent before they can be used.
  string language_code = 2;
}

// The request message for [Pages.CreatePage][google.cloud.dialogflow.cx.v3beta1.Pages.CreatePage].
message CreatePageRequest {
  // Required. The flow to create a page for.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/flows/<Flow ID>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dialogflow.googleapis.com/Page"
    }
  ];

  // Required. The page to create.
  Page page = 2 [(google.api.field_behavior) = REQUIRED];

  // The language of the following fields in `page`:
  //
  // *  `Page.entry_fulfillment.messages`
  // *  `Page.entry_fulfillment.conditional_cases`
  // *  `Page.event_handlers.trigger_fulfillment.messages`
  // *  `Page.event_handlers.trigger_fulfillment.conditional_cases`
  // *  `Page.form.parameters.fill_behavior.initial_prompt_fulfillment.messages`
  // *
  // `Page.form.parameters.fill_behavior.initial_prompt_fulfillment.conditional_cases`
  // *  `Page.form.parameters.fill_behavior.reprompt_event_handlers.messages`
  // *
  // `Page.form.parameters.fill_behavior.reprompt_event_handlers.conditional_cases`
  // *  `Page.transition_routes.trigger_fulfillment.messages`
  // *  `Page.transition_routes.trigger_fulfillment.conditional_cases`
  //
  // If not specified, the agent's default language is used.
  // [Many
  // languages](https://cloud.google.com/dialogflow/cx/docs/reference/language)
  // are supported.
  // Note: languages must be enabled in the agent before they can be used.
  string language_code = 3;
}

// The request message for [Pages.UpdatePage][google.cloud.dialogflow.cx.v3beta1.Pages.UpdatePage].
message UpdatePageRequest {
  // Required. The page to update.
  Page page = 1 [(google.api.field_behavior) = REQUIRED];

  // The language of the following fields in `page`:
  //
  // *  `Page.entry_fulfillment.messages`
  // *  `Page.entry_fulfillment.conditional_cases`
  // *  `Page.event_handlers.trigger_fulfillment.messages`
  // *  `Page.event_handlers.trigger_fulfillment.conditional_cases`
  // *  `Page.form.parameters.fill_behavior.initial_prompt_fulfillment.messages`
  // *
  // `Page.form.parameters.fill_behavior.initial_prompt_fulfillment.conditional_cases`
  // *  `Page.form.parameters.fill_behavior.reprompt_event_handlers.messages`
  // *
  // `Page.form.parameters.fill_behavior.reprompt_event_handlers.conditional_cases`
  // *  `Page.transition_routes.trigger_fulfillment.messages`
  // *  `Page.transition_routes.trigger_fulfillment.conditional_cases`
  //
  // If not specified, the agent's default language is used.
  // [Many
  // languages](https://cloud.google.com/dialogflow/cx/docs/reference/language)
  // are supported.
  // Note: languages must be enabled in the agent before they can be used.
  string language_code = 2;

  // The mask to control which fields get updated. If the mask is not present,
  // all fields will be updated.
  google.protobuf.FieldMask update_mask = 3;
}

// The request message for [Pages.DeletePage][google.cloud.dialogflow.cx.v3beta1.Pages.DeletePage].
message DeletePageRequest {
  // Required. The name of the page to delete.
  // Format: `projects/<Project ID>/locations/<Location ID>/agents/<Agent
  // ID>/Flows/<flow ID>/pages/<Page ID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Page"
    }
  ];

  // This field has no effect for pages with no incoming transitions.
  // For pages with incoming transitions:
  //
  // *  If `force` is set to false, an error will be returned with message
  //    indicating the incoming transitions.
  // *  If `force` is set to true, Dialogflow will remove the page, as well as
  //    any transitions to the page (i.e. [Target
  //    page][EventHandler.target_page] in event handlers or [Target
  //    page][TransitionRoute.target_page] in transition routes that point to
  //    this page will be cleared).
  bool force = 2;
}
