syntax = "proto3";

package wix.devcenter.components.experiments.v1;
option java_package = "com.wixpress.devcenter.components.experiments.v1";

import "google/protobuf/wrappers.proto";
import "google/api/annotations.proto";
import "wix/api/annotations.proto";
import "wix/api/callback.proto";
import "wix/api/entity.proto";
import "wix/api/permissions.proto";
import "wix/api/validations.proto";
import "wix/devcenter/components/experiments/v1/component_experiment.proto";
import "wix/common/bulk.proto";

/**
  Manages ComponentExperiments
 */
service ComponentExperiments {
    option (.wix.api.service_maturity) = BETA;
    option (.wix.api.service_exposure) = PUBLIC;
    option (.wix.api.service_entity).message = "wix.devcenter.components.experiments.v1.ComponentExperiment";

    /**
      Creates a new ComponentExperiment
     */
    rpc CreateComponentExperiment (CreateComponentExperimentRequest) returns (CreateComponentExperimentResponse) {
        option (google.api.http).post = "/v1/component-experiments";
        option (.wix.api.crud) = {
            method: CREATE
            create_options: {
                item_field: "component_experiment"
            }
        };
        option (.wix.api.permission) = {
            name: "DEV_CENTER.MANAGE_COMPONENTS"
            type: MANUAL
        };
        option (.wix.api.additional_permission) = {
            name: "DEV_CENTER.WRITE_COMPONENT"
            type: MANUAL
        };
        option (.wix.api.callback) = {
            event_type: CREATED
        };
    }

    /**
      Get experiment by app id and component id
     */
    rpc GetComponentExperiment (GetComponentExperimentRequest) returns (GetComponentExperimentResponse) {
        option (google.api.http).get = "/v1/component-experiments/fetch-by";
        option (.wix.api.required) = "GetComponentExperimentRequest.app_id";
        option (.wix.api.required) = "GetComponentExperimentRequest.component_id";
        option (.wix.api.permission) = {
            name: "DEVCENTER.READ_COMPONENTS"
            type: MANUAL
        };
        option (.wix.api.additional_permission) = {
            name: "DEV_CENTER.READ_COMPONENT"
            type: MANUAL
        };
    }

    /**
    Get experiments by app id
 */
    rpc ListAppComponentExperiments (ListAppComponentExperimentsRequest) returns (ListAppComponentExperimentsResponse) {
        option (google.api.http).get = "/v1/component-experiments/fetch-by/app-id";
        option (.wix.api.required) = "ListAppComponentExperimentsRequest.app_id";
        option (.wix.api.permission) = {
            name: "DEVCENTER.READ_COMPONENTS"
            type: MANUAL
        };
        option (.wix.api.additional_permission) = {
            name: "DEV_CENTER.READ_COMPONENT"
            type: MANUAL
        };
    }

    /**
      Update a ComponentExperiment, supports partial update
      Pass the latest `revision` for a successful update
     */
    rpc UpdateComponentExperiment (UpdateComponentExperimentRequest) returns (UpdateComponentExperimentResponse) {
        option (google.api.http).patch = "/v1/component-experiments";
        option (.wix.api.required) = "UpdateComponentExperimentRequest.component_experiment";
        option (.wix.api.required) = "UpdateComponentExperimentRequest.component_experiment.app_id";
        option (.wix.api.required) = "UpdateComponentExperimentRequest.component_experiment.component_id";
        option (.wix.api.permission) = {
            name: "DEV_CENTER.MANAGE_COMPONENTS"
            type: MANUAL
        };
        option (.wix.api.additional_permission) = {
            name: "DEV_CENTER.WRITE_COMPONENT"
            type: MANUAL
        };
        option (.wix.api.callback) = {
            event_type: UPDATED
        };
    }

    /**
      Merge a Component Experiment
     */
    rpc EndComponentExperiment (EndComponentExperimentRequest) returns (EndComponentExperimentResponse) {
        option (google.api.http).post = "/v1/component-experiments/merge";
        option (.wix.api.required) = "EndComponentExperimentRequest.app_id";
        option (.wix.api.required) = "EndComponentExperimentRequest.component_id";
        option (.wix.api.permission) = {
            name: "DEV_CENTER.MANAGE_COMPONENTS"
            type: MANUAL
        };
        option (.wix.api.additional_permission) = {
            name: "DEV_CENTER.WRITE_COMPONENT"
            type: MANUAL
        };
        option (.wix.api.callback) = {
            event_type: ACTION
            payload: "wix.devcenter.components.experiments.v1.ComponentExperimentEndedEvent"
        };
    }

    /**
      List experiments by component ids
     */
    rpc ListAppComponentExperimentsByComponentIds (ListAppComponentExperimentsByComponentIdsRequest) returns (ListAppComponentExperimentsByComponentIdsResponse) {
        option (google.api.http).post = "/v1/component-experiments/fetch-by/component-ids";
        option (.wix.api.permission) = {
            name: "DEVCENTER.READ_COMPONENTS"
            type: MANUAL
        };

    }

    /**
      Upsert experiments.
      All experiments must be related to the same app id.
      Key for the upsert is appId + componentId
     */
    rpc UpsertExperiments (UpsertExperimentsRequest) returns (UpsertExperimentsResponse) {
        option (google.api.http).post = "/v1/component-experiments/upsert";
        option (.wix.api.permission) = {
            name: "DEV_CENTER.MANAGE_COMPONENTS"
            type: MANUAL
        };
        option (.wix.api.crud) = {
            method: BULK_UPSERT
            bulk_upsert_options: {
                item_field: "component_experiments"
            }
        };
        option (.wix.api.callback) = {
            event_type: CREATED,
        };
        option (.wix.api.callback) = {
            event_type: UPDATED,
        };
    }
}

message CreateComponentExperimentRequest {
    // ComponentExperiment to be created
    ComponentExperiment component_experiment = 1;
    /* The default behaviour of creating a new experiment is for the service to automatically calculate if the experiment
    should be of type create or update. By opting out we will rely on what passed in the request. */
    bool opt_out_auto_choose = 2;
}

message CreateComponentExperimentResponse {
    ComponentExperiment component_experiment = 1; // The created ComponentExperiment
}

message GetComponentExperimentRequest {
    string app_id = 1 [(.wix.api.format) = GUID]; // App id of the component experiment
    string component_id = 2 [(.wix.api.format) = GUID]; // Component id of the component experiment
}

message GetComponentExperimentResponse {
    ComponentExperiment component_experiment = 1; // The retrieved ComponentExperiment
}

message ListAppComponentExperimentsRequest {
    string app_id = 1 [(.wix.api.format) = GUID]; // App id of the component experiment
    bool consistent = 2; // Fetch consistent data
}

message ListAppComponentExperimentsResponse {
    repeated ComponentExperiment component_experiment = 1; // The retrieved ComponentExperiments
}

message UpdateComponentExperimentRequest {
    ComponentExperiment component_experiment = 1; // The updated component experiment
}

message UpdateComponentExperimentResponse {
    ComponentExperiment component_experiment = 1; // The updated ComponentExperiment
}

message EndComponentExperimentRequest {
    string app_id = 1 [(.wix.api.format) = GUID]; // App id of the component experiment
    string component_id = 2 [(.wix.api.format) = GUID]; // Component id of the component experiment
    Action action = 3; // Action to perform on the experiment
}

message EndComponentExperimentResponse {
}

enum Action {
    MERGE = 0; // Merge the experiment and use the winning version as new version
    FALLBACK = 1; // Use the fallback version for the new version. Delete the component if there is no fallback version
}

message ComponentExperimentEndedEvent {
    ComponentExperiment component_experiment = 1; // Component experiment
    Action action = 2; // The action that happened to the component experiment
}

message ListAppComponentExperimentsByComponentIdsRequest {
    string app_id = 1 [(.wix.api.format) = GUID]; // App id of the component experiment
    repeated string component_ids = 2  [(.wix.api.format) = GUID, (.wix.api.maxSize) = 100]; // Component ids of the component experiment
}

message ListAppComponentExperimentsByComponentIdsResponse {
    repeated ComponentExperiment component_experiment = 1; // The retrieved ComponentExperiments
}

message UpsertExperimentsRequest {
    repeated ComponentExperiment component_experiments = 1 [(wix.api.maxSize) = 100]; // The component experiments to upsert
}

message UpsertExperimentsResponse {
    repeated UpsertResult upsert_result = 1; // The upsert result
    wix.common.BulkActionMetadata bulk_action_metadata = 2; // The bulk action metadata
}

message UpsertResult {
    wix.common.BulkActionType action = 1;
    wix.common.ItemMetadata item_metadata = 2;
    ComponentExperiment component_experiment = 3;
}

message CleanDbRequest {}

message CleanDbResponse {}
