// Copyright 2026 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.bigquery.migration.v2;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/bigquery/migration/v2/assessment_task.proto";
import "google/cloud/bigquery/migration/v2/migration_error_details.proto";
import "google/cloud/bigquery/migration/v2/migration_metrics.proto";
import "google/cloud/bigquery/migration/v2/translation_config.proto";
import "google/cloud/bigquery/migration/v2/translation_details.proto";
import "google/cloud/bigquery/migration/v2/translation_usability.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/error_details.proto";

option csharp_namespace = "Google.Cloud.BigQuery.Migration.V2";
option go_package = "cloud.google.com/go/bigquery/migration/apiv2/migrationpb;migrationpb";
option java_multiple_files = true;
option java_outer_classname = "MigrationEntitiesProto";
option java_package = "com.google.cloud.bigquery.migration.v2";
option php_namespace = "Google\\Cloud\\BigQuery\\Migration\\V2";

// A migration workflow which specifies what needs to be done for an EDW
// migration.
message MigrationWorkflow {
  option (google.api.resource) = {
    type: "bigquerymigration.googleapis.com/MigrationWorkflow"
    pattern: "projects/{project}/locations/{location}/workflows/{workflow}"
  };

  // Possible migration workflow states.
  enum State {
    // Workflow state is unspecified.
    STATE_UNSPECIFIED = 0;

    // Workflow is in draft status, i.e. tasks are not yet eligible for
    // execution.
    DRAFT = 1;

    // Workflow is running (i.e. tasks are eligible for execution).
    RUNNING = 2;

    // Workflow is paused. Tasks currently in progress may continue, but no
    // further tasks will be scheduled.
    PAUSED = 3;

    // Workflow is complete. There should not be any task in a non-terminal
    // state, but if they are (e.g. forced termination), they will not be
    // scheduled.
    COMPLETED = 4;
  }

  // Output only. Immutable. Identifier. The unique identifier for the migration
  // workflow. The ID is server-generated.
  //
  // Example: `projects/123/locations/us/workflows/345`
  string name = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.field_behavior) = IMMUTABLE,
    (google.api.field_behavior) = IDENTIFIER
  ];

  // The display name of the workflow. This can be set to give a workflow
  // a descriptive name. There is no guarantee or enforcement of uniqueness.
  string display_name = 6;

  // The tasks in a workflow in a named map. The name (i.e. key) has no
  // meaning and is merely a convenient way to address a specific task
  // in a workflow.
  map<string, MigrationTask> tasks = 2;

  // Output only. That status of the workflow.
  State state = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the workflow was created.
  google.protobuf.Timestamp create_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the workflow was last updated.
  google.protobuf.Timestamp last_update_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A single task for a migration which has details about the configuration of
// the task.
message MigrationTask {
  // Possible states of a migration task.
  enum State {
    // The state is unspecified.
    STATE_UNSPECIFIED = 0;

    // The task is waiting for orchestration.
    PENDING = 1;

    // The task is assigned to an orchestrator.
    ORCHESTRATING = 2;

    // The task is running, i.e. its subtasks are ready for execution.
    RUNNING = 3;

    // The task is paused. Assigned subtasks can continue, but no new subtasks
    // will be scheduled.
    PAUSED = 4;

    // The task finished successfully.
    SUCCEEDED = 5;

    // The task finished unsuccessfully.
    FAILED = 6;
  }

  // The details of the task.
  oneof task_details {
    // Task configuration for Assessment.
    AssessmentTaskDetails assessment_task_details = 12;

    // Task configuration for CW Batch/Offline SQL Translation.
    TranslationConfigDetails translation_config_details = 14;

    // Task details for unified SQL Translation.
    TranslationDetails translation_details = 16;
  }

  // Output only. Immutable. The unique identifier for the migration task. The
  // ID is server-generated.
  string id = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // The type of the task. This must be one of the supported task types.
  //
  // Assessment:
  //
  // - `Assessment_Hive` - Assessment for Hive.
  // - `Assessment_Redshift` - Assessment for Redshift.
  // - `Assessment_Snowflake` - Assessment for Snowflake.
  // - `Assessment_Teradata_v2` - Assessment for Teradata.
  // - `Assessment_Oracle` - Assessment for Oracle.
  // - `Assessment_Hadoop` - Assessment for Hadoop.
  // - `Assessment_Informatica` - Assessment for Informatica.
  //
  // Translation:
  // See [Supported Task
  // Types](https://docs.cloud.google.com/bigquery/docs/api-sql-translator#supported_task_types)
  // for a list of supported task types.
  string type = 2;

  // Output only. The current state of the task.
  State state = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. An explanation that may be populated when the task is in
  // FAILED state.
  google.rpc.ErrorInfo processing_error = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the task was created.
  google.protobuf.Timestamp create_time = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the task was last updated.
  google.protobuf.Timestamp last_update_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Provides details to errors and issues encountered while
  // processing the task. Presence of error details does not mean that the task
  // failed.
  repeated ResourceErrorDetail resource_error_details = 17
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The number or resources with errors. Note: This is not the
  // total number of errors as each resource can have more than one error. This
  // is used to indicate truncation by having a `resource_error_count` that is
  // higher than the size of `resource_error_details`.
  int32 resource_error_count = 18 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The metrics for the task.
  repeated TimeSeries metrics = 19 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The result of the task.
  MigrationTaskResult task_result = 20
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Count of all the processing errors in this task and its
  // subtasks.
  int32 total_processing_error_count = 21
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Count of all the resource errors in this task and its
  // subtasks.
  int32 total_resource_error_count = 22
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A subtask for a migration which carries details about the configuration of
// the subtask. The content of the details should not matter to the end user,
// but is a contract between the subtask creator and subtask worker.
message MigrationSubtask {
  option (google.api.resource) = {
    type: "bigquerymigration.googleapis.com/MigrationSubtask"
    pattern: "projects/{project}/locations/{location}/workflows/{workflow}/subtasks/{subtask}"
  };

  // Possible states of a migration subtask.
  enum State {
    // The state is unspecified.
    STATE_UNSPECIFIED = 0;

    // The subtask is ready, i.e. it is ready for execution.
    ACTIVE = 1;

    // The subtask is running, i.e. it is assigned to a worker for execution.
    RUNNING = 2;

    // The subtask finished successfully.
    SUCCEEDED = 3;

    // The subtask finished unsuccessfully.
    FAILED = 4;

    // The subtask is paused, i.e., it will not be scheduled. If it was already
    // assigned,it might still finish but no new lease renewals will be granted.
    PAUSED = 5;

    // The subtask is pending a dependency. It will be scheduled once its
    // dependencies are done.
    PENDING_DEPENDENCY = 6;
  }

  // Output only. Immutable. The resource name for the migration subtask. The ID
  // is server-generated.
  //
  // Example: `projects/123/locations/us/workflows/345/subtasks/678`
  string name = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // The unique ID of the task to which this subtask belongs.
  string task_id = 2;

  // The type of the Subtask. The migration service does not check whether this
  // is a known type. It is up to the task creator (i.e. orchestrator or worker)
  // to ensure it only creates subtasks for which there are compatible workers
  // polling for Subtasks.
  string type = 3;

  // Output only. The current state of the subtask.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. An explanation that may be populated when the task is in
  // FAILED state.
  google.rpc.ErrorInfo processing_error = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Provides details to errors and issues encountered while
  // processing the subtask. Presence of error details does not mean that the
  // subtask failed.
  repeated ResourceErrorDetail resource_error_details = 12
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The number or resources with errors. Note: This is not the
  // total number of errors as each resource can have more than one error. This
  // is used to indicate truncation by having a `resource_error_count` that is
  // higher than the size of `resource_error_details`.
  int32 resource_error_count = 13 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the subtask was created.
  google.protobuf.Timestamp create_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the subtask was last updated.
  google.protobuf.Timestamp last_update_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The metrics for the subtask.
  repeated TimeSeries metrics = 11 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// The migration task result.
message MigrationTaskResult {
  // Details specific to the task type.
  oneof details {
    // Details specific to translation task types.
    TranslationTaskResult translation_task_result = 2;
  }

  // The map of task output types to the task outputs, e.g. "LINEAGE".
  map<string, TaskOutput> task_outputs = 3;
}

// Translation specific result details from the migration task.
message TranslationTaskResult {
  // The list of the translated literals.
  repeated Literal translated_literals = 1;

  // The records from the aggregate CSV report for a migration workflow.
  repeated GcsReportLogMessage report_log_messages = 2;

  // The Cloud Console URI for the migration workflow.
  string console_uri = 3;
}

// The task output for a task type including the status and any errors.
message TaskOutput {
  // Possible task output states.
  enum State {
    // Task output state is unspecified.
    STATE_UNSPECIFIED = 0;

    // Task output is pending.
    PENDING = 1;

    // Task output is succeeded.
    SUCCEEDED = 2;

    // Task output is failed. This does not mean that there is no useful
    // information in the output; partial outputs or failure details may be
    // available.
    FAILED = 3;
  }

  // The detailed output of the task.
  oneof output {
    // The output of the task with output type "LINEAGE".
    LineageOutput lineage_output = 3;
  }

  // Output only. The current state of the task output.
  State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // An explanation that may be populated when the task output is in FAILED
  // state.
  google.rpc.ErrorInfo processing_error = 2;
}

// The output of a task with output type "LINEAGE".
//
// Actual generated lineage can be queried separately (see
// [webapp_uri][google.cloud.bigquery.migration.v2.LineageOutput.webapp_uri]),
// this message contains only metadata: processing status, errors, etc.
message LineageOutput {
  // Information about lineage input of the given type that lineage generation
  // recognized.
  //
  // If you expected to process more of the given input, verify your input was
  // uploaded and is in the correct format and the request to generate lineage
  // correctly specified the input location.
  message RecognizedInput {
    // Input type recognized by the lineage processing.
    enum Type {
      // The type is not specified.
      TYPE_UNSPECIFIED = 0;

      // The input is metadata.
      METADATA = 1;

      // The input is a query log.
      QUERY_LOG = 2;

      // The input is a SQL script.
      SCRIPT = 3;
    }

    // Output only. The type of the input.
    Type type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The uncompressed size of the recognized input of the given
    // type.
    int64 uncompressed_size_bytes = 2
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Breaks down processing progress of work.
  message ProgressReport {
    // Summary of work in the given state.
    message WorkSummary {
      // States of work. Each piece of work is in exactly one state.
      // [SUCCEEDED], [FAILED] and [SKIPPED] are terminal states; work in the
      // [IN_PROGRESS] will eventually transition to one of the terminal states.
      enum State {
        // The state is not specified.
        STATE_UNSPECIFIED = 0;

        // Work that was processed successfully.
        SUCCEEDED = 1;

        // Work that failed processing.
        FAILED = 2;

        // Work that is currently being processed or queued for processing.
        IN_PROGRESS = 3;

        // Work that was recognised as necessary to fully process inputs but was
        // skipped due to system limitations.
        SKIPPED = 4;
      }

      // Output only. The state of the work this summary describes.
      State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. Size of the work in the given State.
      //
      // Size counts "units of work". Units represent arbitrary division of
      // work; there's no expectation each unit takes similar time to process.
      int64 size = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. Human-readable comment.
      string comment = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
    }

    // The processing stage the progress report describes.
    enum ProcessingStage {
      // The stage is not specified.
      PROCESSING_STAGE_UNSPECIFIED = 0;

      // The input ingestion stage.
      INPUT_INGESTION = 1000;

      // The lineage DB postprocessing stage.
      POSTPROCESSING = 2000;
    }

    // Output only. The processing stage this progress report describes.
    ProcessingStage processing_stage = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Summaries of work broken up by the state of the work. Each
    // work summary describes how much work is in the given state.
    //
    // To get numbers for the total work covered, aggregate the numbers from all
    // summaries.
    repeated WorkSummary work_summaries = 2
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // The URI of the webapp that visualizes the lineage.
  // The user needs the `bigquerymigration.googleapis.com/lineageDbs.query` IAM
  // permission to use the webapp.
  string webapp_uri = 1;

  // Output only. Recognized lineage inputs.
  //
  // All inputs are processed only if the task succeeds and all work is in state
  // [SUCCEEDED](ProgressReport.WorkSummary.State.SUCCEEDED) (in particular,
  // nothing is [SKIPPED](ProgressReport.WorkSummary.State.SKIPPED)).
  //
  // Even with all inputs processed successfully, there may be transpiler errors
  // present leading to inaccurate lineage.
  repeated RecognizedInput recognized_inputs = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Work processing progress reports broken up by processing
  // stage.
  repeated ProgressReport processing_progress_reports = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];
}
