// Copyright 2023 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.clouddms.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/clouddms/v1/clouddms_resources.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.CloudDms.V1";
option go_package = "cloud.google.com/go/clouddms/apiv1/clouddmspb;clouddmspb";
option java_multiple_files = true;
option java_outer_classname = "ConversionWorkspaceResourcesProto";
option java_package = "com.google.cloud.clouddms.v1";
option php_namespace = "Google\\Cloud\\CloudDms\\V1";
option ruby_package = "Google::Cloud::CloudDMS::V1";

// The type and version of a source or destination database.
message DatabaseEngineInfo {
  // Required. Engine type.
  DatabaseEngine engine = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Engine named version, for example 12.c.1.
  string version = 2 [(google.api.field_behavior) = REQUIRED];
}

// The main conversion workspace resource entity.
message ConversionWorkspace {
  option (google.api.resource) = {
    type: "datamigration.googleapis.com/ConversionWorkspace"
    pattern: "projects/{project}/locations/{location}/conversionWorkspaces/{conversion_workspace}"
  };

  // Full name of the workspace resource, in the form of:
  // projects/{project}/locations/{location}/conversionWorkspaces/{conversion_workspace}.
  string name = 1;

  // Required. The source engine details.
  DatabaseEngineInfo source = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The destination engine details.
  DatabaseEngineInfo destination = 3 [(google.api.field_behavior) = REQUIRED];

  // A generic list of settings for the workspace.
  // The settings are database pair dependant and can indicate default behavior
  // for the mapping rules engine or turn on or off specific features.
  // Such examples can be: convert_foreign_key_to_interleave=true,
  // skip_triggers=false, ignore_non_table_synonyms=true
  map<string, string> global_settings = 4;

  // Output only. Whether the workspace has uncommitted changes (changes which
  // were made after the workspace was committed).
  bool has_uncommitted_changes = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The latest commit ID.
  string latest_commit_id = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp when the workspace was committed.
  google.protobuf.Timestamp latest_commit_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp when the workspace resource was created.
  google.protobuf.Timestamp create_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp when the workspace resource was last updated.
  google.protobuf.Timestamp update_time = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The display name for the workspace.
  string display_name = 11;
}

// Execution log of a background job.
message BackgroundJobLogEntry {
  // Final state after a job completes.
  enum JobCompletionState {
    // The status is not specified. This state is used when job is not yet
    // finished.
    JOB_COMPLETION_STATE_UNSPECIFIED = 0;

    // Success.
    SUCCEEDED = 1;

    // Error.
    FAILED = 2;
  }

  // Details regarding a Seed background job.
  message SeedJobDetails {
    // The connection profile which was used for the seed job.
    string connection_profile = 1;
  }

  // Details regarding an Import Rules background job.
  message ImportRulesJobDetails {
    // File names used for the import rules job.
    repeated string files = 1;

    // The requested file format.
    ImportRulesFileFormat file_format = 2;
  }

  // Details regarding a Convert background job.
  message ConvertJobDetails {
    // AIP-160 based filter used to specify the entities to convert
    string filter = 1;
  }

  // Details regarding an Apply background job.
  message ApplyJobDetails {
    // The connection profile which was used for the apply job.
    string connection_profile = 1;

    // AIP-160 based filter used to specify the entities to apply
    string filter = 2;
  }

  // The background job log entry ID.
  string id = 1;

  // The type of job that was executed.
  BackgroundJobType job_type = 2;

  // The timestamp when the background job was started.
  google.protobuf.Timestamp start_time = 3;

  // The timestamp when the background job was finished.
  google.protobuf.Timestamp finish_time = 4;

  // Job completion state, i.e. the final state after the job completed.
  JobCompletionState completion_state = 5;

  // Job completion comment, such as how many entities were seeded,
  // how many warnings were found during conversion, and similar information.
  string completion_comment = 6;

  // Whether the client requested the conversion workspace to be committed after
  // a successful completion of the job.
  bool request_autocommit = 7;

  oneof job_details {
    // Seed job details.
    SeedJobDetails seed_job_details = 100;

    // Import rules job details.
    ImportRulesJobDetails import_rules_job_details = 101;

    // Convert job details.
    ConvertJobDetails convert_job_details = 102;

    // Apply job details.
    ApplyJobDetails apply_job_details = 103;
  }
}

// The base entity type for all the database related entities.
// The message contains the entity name, the name of its parent, the entity
// type, and the specific details per entity type.
message DatabaseEntity {
  // The type of database entities tree.
  enum TreeType {
    // Tree type unspecified.
    TREE_TYPE_UNSPECIFIED = 0;

    // Tree of entities loaded from a source database.
    SOURCE = 1;

    // Tree of entities converted from the source tree using the mapping rules.
    DRAFT = 2;

    // Tree of entities observed on the destination database.
    DESTINATION = 3;
  }

  // The short name (e.g. table name) of the entity.
  string short_name = 1;

  // The full name of the parent entity (e.g. schema name).
  string parent_entity = 2;

  // The type of tree the entity belongs to.
  TreeType tree = 3;

  // The type of the database entity (table, view, index, ...).
  DatabaseEntityType entity_type = 4;

  // Details about entity mappings.
  // For source tree entities, this holds the draft entities which were
  // generated by the mapping rules.
  // For draft tree entities, this holds the source entities which were
  // converted to form the draft entity.
  // Destination entities will have no mapping details.
  repeated EntityMapping mappings = 5;

  // The specific body for each entity type.
  oneof entity_body {
    // Schema.
    SchemaEntity schema = 102;

    // Table.
    TableEntity table = 103;

    // View.
    ViewEntity view = 104;

    // Sequence.
    SequenceEntity sequence = 105;

    // Stored procedure.
    StoredProcedureEntity stored_procedure = 106;

    // Function.
    FunctionEntity database_function = 107;

    // Synonym.
    SynonymEntity synonym = 108;

    // Package.
    PackageEntity database_package = 109;
  }
}

// Schema typically has no parent entity, but can have a parent entity
// DatabaseInstance (for database engines which support it).  For some database
// engines, the terms  schema and user can be used interchangeably when they
// refer to a namespace or a collection of other database entities. Can store
// additional information which is schema specific.
message SchemaEntity {
  // Custom engine specific features.
  google.protobuf.Struct custom_features = 1;
}

// Table's parent is a schema.
message TableEntity {
  // Table columns.
  repeated ColumnEntity columns = 1;

  // Table constraints.
  repeated ConstraintEntity constraints = 2;

  // Table indices.
  repeated IndexEntity indices = 3;

  // Table triggers.
  repeated TriggerEntity triggers = 4;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 5;

  // Comment associated with the table.
  string comment = 6;
}

// Column is not used as an independent entity, it is retrieved as part of a
// Table entity.
message ColumnEntity {
  // Column name.
  string name = 1;

  // Column data type.
  string data_type = 2;

  // Charset override - instead of table level charset.
  string charset = 3;

  // Collation override - instead of table level collation.
  string collation = 4;

  // Column length - e.g. varchar (50).
  int64 length = 5;

  // Column precision - when relevant.
  int32 precision = 6;

  // Column scale - when relevant.
  int32 scale = 7;

  // Column fractional second precision - used for timestamp based datatypes.
  int32 fractional_seconds_precision = 8;

  // Is the column of array type.
  bool array = 9;

  // If the column is array, of which length.
  int32 array_length = 10;

  // Is the column nullable.
  bool nullable = 11;

  // Is the column auto-generated/identity.
  bool auto_generated = 12;

  // Is the column a UDT.
  bool udt = 13;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 14;

  // Specifies the list of values allowed in the column.
  // Only used for set data type.
  repeated string set_values = 15;

  // Comment associated with the column.
  string comment = 16;

  // Column order in the table.
  int32 ordinal_position = 17;

  // Default value of the column.
  string default_value = 18;
}

// Constraint is not used as an independent entity, it is retrieved
// as part of another entity such as Table or View.
message ConstraintEntity {
  // The name of the table constraint.
  string name = 1;

  // Type of constraint, for example unique, primary key, foreign key (currently
  // only primary key is supported).
  string type = 2;

  // Table columns used as part of the Constraint, for example primary key
  // constraint should list the columns which constitutes the key.
  repeated string table_columns = 3;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 4;

  // Reference columns which may be associated with the constraint. For example,
  // if the constraint is a FOREIGN_KEY, this represents the list of full names
  // of referenced columns by the foreign key.
  repeated string reference_columns = 5;

  // Reference table which may be associated with the constraint. For example,
  // if the constraint is a FOREIGN_KEY, this represents the list of full name
  // of the referenced table by the foreign key.
  string reference_table = 6;

  // Table which is associated with the constraint. In case the constraint
  // is defined on a table, this field is left empty as this information is
  // stored in parent_name. However, if constraint is defined on a view, this
  // field stores the table name on which the view is defined.
  string table_name = 7;
}

// Index is not used as an independent entity, it is retrieved as part of a
// Table entity.
message IndexEntity {
  // The name of the index.
  string name = 1;

  // Type of index, for example B-TREE.
  string type = 2;

  // Table columns used as part of the Index, for example B-TREE index should
  // list the columns which constitutes the index.
  repeated string table_columns = 3;

  // Boolean value indicating whether the index is unique.
  bool unique = 4;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 5;
}

// Trigger is not used as an independent entity, it is retrieved as part of a
// Table entity.
message TriggerEntity {
  // The name of the trigger.
  string name = 1;

  // The DML, DDL, or database events that fire the trigger, for example
  // INSERT, UPDATE.
  repeated string triggering_events = 2;

  // Indicates when the trigger fires, for example BEFORE STATEMENT, AFTER EACH
  // ROW.
  string trigger_type = 3;

  // The SQL code which creates the trigger.
  string sql_code = 4;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 5;
}

// View's parent is a schema.
message ViewEntity {
  // The SQL code which creates the view.
  string sql_code = 1;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 2;

  // View constraints.
  repeated ConstraintEntity constraints = 3;
}

// Sequence's parent is a schema.
message SequenceEntity {
  // Increment value for the sequence.
  int64 increment = 1;

  // Start number for the sequence represented as bytes to accommodate large.
  // numbers
  bytes start_value = 2;

  // Maximum number for the sequence represented as bytes to accommodate large.
  // numbers
  bytes max_value = 3;

  // Minimum number for the sequence represented as bytes to accommodate large.
  // numbers
  bytes min_value = 4;

  // Indicates whether the sequence value should cycle through.
  bool cycle = 5;

  // Indicates number of entries to cache / precreate.
  int64 cache = 6;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 7;
}

// Stored procedure's parent is a schema.
message StoredProcedureEntity {
  // The SQL code which creates the stored procedure.
  string sql_code = 1;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 2;
}

// Function's parent is a schema.
message FunctionEntity {
  // The SQL code which creates the function.
  string sql_code = 1;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 2;
}

// Synonym's parent is a schema.
message SynonymEntity {
  // The name of the entity for which the synonym is being created (the source).
  string source_entity = 1;

  // The type of the entity for which the synonym is being created
  // (usually a table or a sequence).
  DatabaseEntityType source_type = 2;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 3;
}

// Package's parent is a schema.
message PackageEntity {
  // The SQL code which creates the package.
  string package_sql_code = 1;

  // The SQL code which creates the package body. If the package specification
  // has cursors or subprograms, then the package body is mandatory.
  string package_body = 2;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 3;
}

// Details of the mappings of a database entity.
message EntityMapping {
  // Source entity full name.
  // The source entity can also be a column, index or constraint using the
  // same naming notation schema.table.column.
  string source_entity = 1;

  // Target entity full name.
  // The draft entity can also include a column, index or constraint using the
  // same naming notation schema.table.column.
  string draft_entity = 2;

  // Type of source entity.
  DatabaseEntityType source_type = 4;

  // Type of draft entity.
  DatabaseEntityType draft_type = 5;

  // Entity mapping log entries.
  // Multiple rules can be effective and contribute changes to a converted
  // entity, such as a rule can handle the entity name, another rule can handle
  // an entity type. In addition, rules which did not change the entity are also
  // logged along with the reason preventing them to do so.
  repeated EntityMappingLogEntry mapping_log = 3;
}

// A single record of a rule which was used for a mapping.
message EntityMappingLogEntry {
  // Which rule caused this log entry.
  string rule_id = 1;

  // Rule revision ID.
  string rule_revision_id = 2;

  // Comment.
  string mapping_comment = 3;
}

// The type of database entities supported,
enum DatabaseEntityType {
  // Unspecified database entity type.
  DATABASE_ENTITY_TYPE_UNSPECIFIED = 0;

  // Schema.
  DATABASE_ENTITY_TYPE_SCHEMA = 1;

  // Table.
  DATABASE_ENTITY_TYPE_TABLE = 2;

  // Column.
  DATABASE_ENTITY_TYPE_COLUMN = 3;

  // Constraint.
  DATABASE_ENTITY_TYPE_CONSTRAINT = 4;

  // Index.
  DATABASE_ENTITY_TYPE_INDEX = 5;

  // Trigger.
  DATABASE_ENTITY_TYPE_TRIGGER = 6;

  // View.
  DATABASE_ENTITY_TYPE_VIEW = 7;

  // Sequence.
  DATABASE_ENTITY_TYPE_SEQUENCE = 8;

  // Stored Procedure.
  DATABASE_ENTITY_TYPE_STORED_PROCEDURE = 9;

  // Function.
  DATABASE_ENTITY_TYPE_FUNCTION = 10;

  // Synonym.
  DATABASE_ENTITY_TYPE_SYNONYM = 11;

  // Package.
  DATABASE_ENTITY_TYPE_DATABASE_PACKAGE = 12;

  // UDT.
  DATABASE_ENTITY_TYPE_UDT = 13;

  // Materialized View.
  DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW = 14;

  // Database.
  DATABASE_ENTITY_TYPE_DATABASE = 15;
}

// The types of jobs that can be executed in the background.
enum BackgroundJobType {
  // Unspecified background job type.
  BACKGROUND_JOB_TYPE_UNSPECIFIED = 0;

  // Job to seed from the source database.
  BACKGROUND_JOB_TYPE_SOURCE_SEED = 1;

  // Job to convert the source database into a draft of the destination
  // database.
  BACKGROUND_JOB_TYPE_CONVERT = 2;

  // Job to apply the draft tree onto the destination.
  BACKGROUND_JOB_TYPE_APPLY_DESTINATION = 3;

  // Job to import and convert mapping rules from an external source such as an
  // ora2pg config file.
  BACKGROUND_JOB_TYPE_IMPORT_RULES_FILE = 5;
}

// The format for the import rules file.
enum ImportRulesFileFormat {
  // Unspecified rules format.
  IMPORT_RULES_FILE_FORMAT_UNSPECIFIED = 0;

  // HarbourBridge session file.
  IMPORT_RULES_FILE_FORMAT_HARBOUR_BRIDGE_SESSION_FILE = 1;

  // Ora2Pg configuration file.
  IMPORT_RULES_FILE_FORMAT_ORATOPG_CONFIG_FILE = 2;
}
