# Copyright (c) 2016, 2023, Oracle and/or its affiliates.
#
# This software is dual-licensed to you under the Universal Permissive License
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
# 2.0 as shown at https://www.apache.org/licenses/LICENSE-2.0. You may choose
# either license.
#
# If you elect to accept the software under the Apache License, Version 2.0,
# the following applies:
#
# 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
#
#     https://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.
# coding: utf-8
from __future__ import print_function

import os

import click  # noqa: F401
import json  # noqa: F401
import base64
from services.database_migration.src.oci_cli_database_migration.generated import databasemigration_cli
from oci_cli import cli_util  # noqa: F401
from oci_cli import custom_types  # noqa: F401
from oci_cli import json_skeleton_utils  # noqa: F401
from oci_cli import cli_exceptions


# oci database-migration agent-image-summary -> oci database-migration agent-image
# cli_util.rename_command(databasemigration_cli, databasemigration_cli.database_migration_root_group, databasemigration_cli.agent_image_summary_group, "agent-image")


# oci database-migration agent-image-summary list-agent-images -> oci database-migration agent-image-summary list
# cli_util.rename_command(databasemigration_cli, databasemigration_cli.agent_image_summary_group, databasemigration_cli.list_agent_images, "list")


# oci database-migration agent-summary list-agents -> oci database-migration agent-summary list
# cli_util.rename_command(databasemigration_cli, databasemigration_cli.agent_summary_group, databasemigration_cli.list_agents, "list")


# oci database-migration connection-summary list-connections -> oci database-migration connection-summary list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.connection_summary_group, databasemigration_cli.list_connections, "list")


# oci database-migration job evaluate-migration -> oci database-migration job evaluate
cli_util.rename_command(databasemigration_cli, databasemigration_cli.job_group, databasemigration_cli.evaluate_migration, "evaluate")


# oci database-migration job start-migration -> oci database-migration job start
cli_util.rename_command(databasemigration_cli, databasemigration_cli.job_group, databasemigration_cli.start_migration, "start")


# oci database-migration job-output-summary -> oci database-migration job-output
cli_util.rename_command(databasemigration_cli, databasemigration_cli.database_migration_root_group, databasemigration_cli.job_output_summary_group, "job-output")


# oci database-migration job-output-summary list-job-outputs -> oci database-migration job-output-summary list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.job_output_summary_group, databasemigration_cli.list_job_outputs, "list")


# oci database-migration job-summary list-jobs -> oci database-migration job-summary list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.job_summary_group, databasemigration_cli.list_jobs, "list")


# oci database-migration migration-summary list-migrations -> oci database-migration migration-summary list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_summary_group, databasemigration_cli.list_migrations, "list")


# oci database-migration work-request-log-entry -> oci database-migration work-request-logs
cli_util.rename_command(databasemigration_cli, databasemigration_cli.database_migration_root_group, databasemigration_cli.work_request_log_entry_group, "work-request-logs")


# oci database-migration work-request-log-entry list-work-request-logs -> oci database-migration work-request-log-entry list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.work_request_log_entry_group, databasemigration_cli.list_work_request_logs, "list")


# oci database-migration work-request-summary list-work-requests -> oci database-migration work-request-summary list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.work_request_summary_group, databasemigration_cli.list_work_requests, "list")


# oci database-migration job evaluate-migration -> oci database-migration migration
databasemigration_cli.job_group.commands.pop(databasemigration_cli.evaluate_migration.name)
databasemigration_cli.migration_group.add_command(databasemigration_cli.evaluate_migration)


# oci database-migration job start-migration -> oci database-migration migration
databasemigration_cli.job_group.commands.pop(databasemigration_cli.start_migration.name)
databasemigration_cli.migration_group.add_command(databasemigration_cli.start_migration)


# oci database-migration agent-summary list-agents -> oci database-migration agent
# databasemigration_cli.agent_summary_group.commands.pop(databasemigration_cli.list_agents.name)
# databasemigration_cli.agent_group.add_command(databasemigration_cli.list_agents)


# oci database-migration connection-summary list-connections -> oci database-migration connection
databasemigration_cli.connection_summary_group.commands.pop(databasemigration_cli.list_connections.name)
databasemigration_cli.connection_group.add_command(databasemigration_cli.list_connections)


# oci database-migration job-summary list-jobs -> oci database-migration job
databasemigration_cli.job_summary_group.commands.pop(databasemigration_cli.list_jobs.name)
databasemigration_cli.job_group.add_command(databasemigration_cli.list_jobs)


# oci database-migration migration-summary list-migrations -> oci database-migration migration
databasemigration_cli.migration_summary_group.commands.pop(databasemigration_cli.list_migrations.name)
databasemigration_cli.migration_group.add_command(databasemigration_cli.list_migrations)


# oci database-migration work-request-summary list-work-requests -> oci database-migration work-request
databasemigration_cli.work_request_summary_group.commands.pop(databasemigration_cli.list_work_requests.name)
databasemigration_cli.work_request_group.add_command(databasemigration_cli.list_work_requests)

# remove groups previously renamed
# databasemigration_cli.database_migration_root_group.commands.pop(databasemigration_cli.agent_summary_group.name)
databasemigration_cli.database_migration_root_group.commands.pop(databasemigration_cli.connection_summary_group.name)
databasemigration_cli.database_migration_root_group.commands.pop(databasemigration_cli.job_summary_group.name)
databasemigration_cli.database_migration_root_group.commands.pop(databasemigration_cli.migration_summary_group.name)
databasemigration_cli.database_migration_root_group.commands.pop(databasemigration_cli.work_request_summary_group.name)


# @cli_util.copy_params_from_generated_command(databasemigration_cli.update_agent, params_to_exclude=['version_parameterconflict'])
# @databasemigration_cli.agent_group.command(name=databasemigration_cli.update_agent.name, help=databasemigration_cli.update_agent.help)
# @cli_util.option('--agent-version', help=u"""ODMS Agent version""")
# @cli_util.option('--public-key-file', type=click.File('r'), help=u"""ODMS Agent public key file path.""")
# @click.pass_context
# @json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'freeform-tags': {'module': 'database_migration', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'database_migration', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'database_migration', 'class': 'Agent'})
# @cli_util.wrap_exceptions
# def update_agent_extended(ctx, **kwargs):
#     if 'agent_version' in kwargs:
#         kwargs['version_parameterconflict'] = kwargs['agent_version']
#         kwargs.pop('agent_version')
#
#     if kwargs.get('public_key') and kwargs.get('public_key_file'):
#         raise cli_exceptions.RequiredValueNotInDefaultOrUserInputError('Cannot specify both --public-key or --public-key-file.')
#
#     key_file = kwargs.get('public_key_file')
#     if key_file:
#         kwargs['public_key'] = key_file.read()
#
#     kwargs.pop('public_key_file')
#
#     ctx.invoke(databasemigration_cli.update_agent, **kwargs)


# oci database-migration connection create --tls-keystore-file --tls-wallet-file  --ssh-details.sshkeyFile
@cli_util.copy_params_from_generated_command(databasemigration_cli.create_connection, params_to_exclude=['manual_database_sub_type'])
@databasemigration_cli.connection_group.command(name='create', help=databasemigration_cli.create_connection.help)
@cli_util.option('--db-subtype', type=custom_types.CliCaseInsensitiveChoice(["ORACLE", "RDS_ORACLE"]), help="""Database manual connection subtype. This value can only be specified for manual connections.""")
@cli_util.option('--tls-wallet-file', type=click.File('r'), help=u"""cwallet.sso fle path containing containing the TCPS/SSL certificate; base64 encoded String. Not required for source container database connections.""")
@cli_util.option('--tls-keystore-file', type=click.File('r'), help=u"""keystore.jks file path; base64 encoded String content. Requires a TLS wallet to be specified. Not required for source container database connections.""")
@cli_util.option('--sshkey-file', type=click.File('r'), help=u""" Private ssh key file.""")
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'connect-descriptor': {'module': 'database_migration', 'class': 'CreateConnectDescriptor'}, 'ssh-details': {'module': 'database_migration', 'class': 'CreateSshDetails'}, 'admin-credentials': {'module': 'database_migration', 'class': 'CreateAdminCredentials'}, 'private-endpoint': {'module': 'database_migration', 'class': 'CreatePrivateEndpoint'}, 'vault-details': {'module': 'database_migration', 'class': 'CreateVaultDetails'}, 'freeform-tags': {'module': 'database_migration', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'database_migration', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'database_migration', 'class': 'Connection'})
@cli_util.wrap_exceptions
def create_connection(ctx, **kwargs):

    if 'db_subtype' in kwargs:
        kwargs['manual_database_sub_type'] = kwargs['db_subtype']
        kwargs.pop('db_subtype')

    # read --sshkey-file into ssh_details['sshkey']
    if 'sshkey_file' in kwargs and kwargs['sshkey_file'] is not None:
        ssh_details = {}
        if 'ssh_details' in kwargs and kwargs['ssh_details'] is not None:
            if ssh_details.get('sshkey') and ssh_details['sshkey'] is not None:
                raise cli_exceptions.RequiredValueNotInDefaultOrUserInputError('Cannot specify both --sshkey-file and sshDetails.sshkey.')
            ssh_details = kwargs['ssh_details']
        sshkey_file = kwargs.get('sshkey_file')
        if sshkey_file:
            ssh_details['sshkey'] = sshkey_file.read()
            kwargs['ssh_details'] = json.dumps(ssh_details)
    kwargs.pop('sshkey_file')

    # create_connection read --tls-wallet using --tls-wallet-file
    if kwargs.get('tls_wallet') and kwargs.get('tls_wallet_file'):
        raise cli_exceptions.RequiredValueNotInDefaultOrUserInputError('Cannot specify both --tls-wallet and --tls-wallet-file.')

    tls_wallet_file = kwargs.get('tls_wallet_file')
    if tls_wallet_file:
        kwargs['tls_wallet'] = tls_wallet_file.read()

    kwargs.pop('tls_wallet_file')

    # create_connection read --tls-keystore using --tls-keystore-file
    if kwargs.get('tls_keystore') and kwargs.get('tls_keystore_file'):
        raise cli_exceptions.RequiredValueNotInDefaultOrUserInputError('Cannot specify both --tls-keystore or --tls-keystore-file.')

    tls_keystore_file = kwargs.get('tls_keystore_file')
    if tls_keystore_file:
        kwargs['tls_keystore'] = tls_keystore_file.read()

    kwargs.pop('tls_keystore_file')

    ctx.invoke(databasemigration_cli.create_connection, **kwargs)


# oci database-migration connection update --tls-keystore-file --tls-wallet-file  --ssh-details.sshkeyFile
@cli_util.copy_params_from_generated_command(databasemigration_cli.update_connection, params_to_exclude=[])
@databasemigration_cli.connection_group.command(name='update', help=databasemigration_cli.update_connection.help)
@cli_util.option('--tls-wallet-file', type=click.File('r'), help=u"""cwallet.sso file path containing containing the TCPS/SSL certificate; base64 encoded String. Not required for source container database connections.""")
@cli_util.option('--tls-keystore-file', type=click.File('r'), help=u"""keystore.jks file path; base64 encoded String contents. Requires a TLS wallet to be specified. Not required for source container database connections.""")
@cli_util.option('--sshkey-file', type=click.File('r'), help=u""" Private ssh key file.""")
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'connect-descriptor': {'module': 'database_migration', 'class': 'UpdateConnectDescriptor'}, 'ssh-details': {'module': 'database_migration', 'class': 'UpdateSshDetails'}, 'admin-credentials': {'module': 'database_migration', 'class': 'UpdateAdminCredentials'}, 'private-endpoint': {'module': 'database_migration', 'class': 'UpdatePrivateEndpoint'}, 'vault-details': {'module': 'database_migration', 'class': 'UpdateVaultDetails'}, 'freeform-tags': {'module': 'database_migration', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'database_migration', 'class': 'dict(str, dict(str, object))'}})
@cli_util.wrap_exceptions
def update_connection(ctx, **kwargs):
    # read --sshkey-file into ssh_details['sshkey']
    if 'sshkey_file' in kwargs and kwargs['sshkey_file'] is not None:
        ssh_details = {}
        if 'ssh_details' in kwargs and kwargs['ssh_details'] is not None:
            if ssh_details.get('sshkey') and ssh_details['sshkey'] is not None:
                raise cli_exceptions.RequiredValueNotInDefaultOrUserInputError('Cannot specify both --sshkey-file and sshDetails.sshkey.')
            ssh_details = kwargs['ssh_details']
        sshkey_file = kwargs.get('sshkey_file')
        if sshkey_file:
            ssh_details['sshkey'] = sshkey_file.read()
            kwargs['ssh_details'] = json.dumps(ssh_details)
    kwargs.pop('sshkey_file')

    # update_connection read --tls-wallet using --tls-wallet-file
    if kwargs.get('tls_wallet') and kwargs.get('tls_wallet_file'):
        raise cli_exceptions.RequiredValueNotInDefaultOrUserInputError('Cannot specify both --tls-wallet or --tls-wallet-file.')

    tls_wallet_file = kwargs.get('tls_wallet_file')
    if tls_wallet_file:
        kwargs['tls_wallet'] = tls_wallet_file.read()

    kwargs.pop('tls_wallet_file')

    # update_connection read --tls-keystore using --tls-keystore-file
    if kwargs.get('tls_keystore') and kwargs.get('tls_keystore_file'):
        raise cli_exceptions.RequiredValueNotInDefaultOrUserInputError('Cannot specify both --tls-keystore or --tls-keystore-file.')

    tls_keystore_file = kwargs.get('tls_keystore_file')
    if tls_keystore_file:
        kwargs['tls_keystore'] = tls_keystore_file.read()

    kwargs.pop('tls_keystore_file')

    ctx.invoke(databasemigration_cli.update_connection, **kwargs)


# @cli_util.copy_params_from_generated_command(databasemigration_cli.create_agent, params_to_exclude=['version_parameterconflict'])
# @databasemigration_cli.agent_group.command(name=databasemigration_cli.create_agent.name, help=databasemigration_cli.create_agent.help)
@cli_util.option('--agent-version', required=True, help=u"""ODMS Agent version [required]""")
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'freeform-tags': {'module': 'database_migration', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'database_migration', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'database_migration', 'class': 'Agent'})
@cli_util.wrap_exceptions
def create_agent_extended(ctx, **kwargs):
    if 'agent_version' in kwargs:
        kwargs['version_parameterconflict'] = kwargs['agent_version']
        kwargs.pop('agent_version')

    ctx.invoke(databasemigration_cli.create_agent, **kwargs)


# oci database-migration migration-object-type-summary list-migration-object-types -> oci database-migration migration-object-type-summary list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_object_type_summary_group, databasemigration_cli.list_migration_object_types, "list")

# oci database-migration excluded-object-summary list-excluded-objects -> oci database-migration excluded-object-summary list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.excluded_object_summary_group, databasemigration_cli.list_excluded_objects, "list")


# oci database-migration migration-object-collection list-migration-objects -> oci database-migration migration-object-collection list
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_object_collection_group, databasemigration_cli.list_migration_objects, "list")


# oci database-migration migration-object-collection -> oci database-migration migration-objects
cli_util.rename_command(databasemigration_cli, databasemigration_cli.database_migration_root_group, databasemigration_cli.migration_object_collection_group, "migration-objects")


# oci database-migration connection create-connection-create-mysql-connection-details -> oci database-migration connection create-mysql-connection
cli_util.rename_command(databasemigration_cli, databasemigration_cli.connection_group, databasemigration_cli.create_connection_create_mysql_connection_details, "create-mysql-connection")


# oci database-migration connection create-connection-create-oracle-connection-details -> oci database-migration connection create-oracle-connection
cli_util.rename_command(databasemigration_cli, databasemigration_cli.connection_group, databasemigration_cli.create_connection_create_oracle_connection_details, "create-oracle-connection")


# oci database-migration connection update-connection-update-mysql-connection-details -> oci database-migration connection update-mysql-connection
cli_util.rename_command(databasemigration_cli, databasemigration_cli.connection_group, databasemigration_cli.update_connection_update_mysql_connection_details, "update-mysql-connection")


# oci database-migration connection update-connection-update-oracle-connection-details -> oci database-migration connection update-oracle-connection
cli_util.rename_command(databasemigration_cli, databasemigration_cli.connection_group, databasemigration_cli.update_connection_update_oracle_connection_details, "update-oracle-connection")


# oci database-migration migration add-migration-objects-my-sql-migration-object-collection -> oci database-migration migration add-mysql-objects
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.add_migration_objects_my_sql_migration_object_collection, "add-mysql-objects")


# oci database-migration migration add-migration-objects-oracle-migration-object-collection -> oci database-migration migration add-oracle-objects
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.add_migration_objects_oracle_migration_object_collection, "add-oracle-objects")


# oci database-migration migration clone-migration-my-sql-clone-migration-details -> oci database-migration migration clone-mysql-migration
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.clone_migration_my_sql_clone_migration_details, "clone-mysql-migration")


# oci database-migration migration clone-migration-oracle-clone-migration-details -> oci database-migration migration clone-oracle-migration
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.clone_migration_oracle_clone_migration_details, "clone-oracle-migration")


# oci database-migration migration create-migration-create-my-sql-migration-details -> oci database-migration migration create-mysql-migration
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.create_migration_create_my_sql_migration_details, "create-mysql-migration")


# oci database-migration migration create-migration-create-oracle-migration-details -> oci database-migration migration create-oracle-migration
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.create_migration_create_oracle_migration_details, "create-oracle-migration")


# oci database-migration migration remove-migration-objects-my-sql-migration-object-collection -> oci database-migration migration remove-mysql-objects
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.remove_migration_objects_my_sql_migration_object_collection, "remove-mysql-objects")


# oci database-migration migration remove-migration-objects-oracle-migration-object-collection -> oci database-migration migration remove-oracle-objects
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.remove_migration_objects_oracle_migration_object_collection, "remove-oracle-objects")


# oci database-migration migration update-migration-update-my-sql-migration-details -> oci database-migration migration update-mysql-migration
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.update_migration_update_my_sql_migration_details, "update-mysql-migration")


# oci database-migration migration update-migration-update-oracle-migration-details -> oci database-migration migration update-oracle-migration
cli_util.rename_command(databasemigration_cli, databasemigration_cli.migration_group, databasemigration_cli.update_migration_update_oracle_migration_details, "update-oracle-migration")


# Remove add from oci database-migration migration
databasemigration_cli.migration_group.commands.pop(databasemigration_cli.add_migration_objects.name)


# Remove clone from oci database-migration migration
databasemigration_cli.migration_group.commands.pop(databasemigration_cli.clone_migration.name)


# Remove create from oci database-migration migration
databasemigration_cli.migration_group.commands.pop(databasemigration_cli.create_migration.name)


# Remove remove from oci database-migration migration
databasemigration_cli.migration_group.commands.pop(databasemigration_cli.remove_migration_objects.name)


# Remove update from oci database-migration migration
databasemigration_cli.migration_group.commands.pop(databasemigration_cli.update_migration.name)


# Remove list from oci database-migration migration-object-type-summary
databasemigration_cli.migration_object_type_summary_group.commands.pop(databasemigration_cli.list_migration_object_types.name)

# Remove create from oci database-migration connection
databasemigration_cli.connection_group.commands.pop(databasemigration_cli.create_connection.name)

# Remove update from oci database-migration connection
databasemigration_cli.connection_group.commands.pop(databasemigration_cli.update_connection.name)


# oci database-migration connection create-oracle-connection --wallet --ssh-key
@cli_util.copy_params_from_generated_command(databasemigration_cli.create_connection_create_oracle_connection_details, params_to_exclude=[])
@databasemigration_cli.connection_group.command(name=cli_util.override('database_migration.create_connection_create_oracle_connection_details.command_name', 'create-connection-create-oracle-connection-details'), help=databasemigration_cli.create_connection_create_oracle_connection_details.help)
@cli_util.option('--technology-type', type=custom_types.CliCaseInsensitiveChoice(["AMAZON_RDS_ORACLE", "OCI_AUTONOMOUS_DATABASE", "ORACLE_DATABASE", "ORACLE_EXADATA"]), help="""The Oracle technology type. This value can only be specified for manual connections.""")
@cli_util.option('--wallet', help=u"""File path to cwallet.sso containing containing the TCPS/SSL certificate.""")
@cli_util.option('--sshkey-file', type=click.File('r'), help=u""" Private ssh key file.""")
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'freeform-tags': {'module': 'database_migration', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'database_migration', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'database_migration', 'class': 'Connection'})
@cli_util.wrap_exceptions
def create_connection_create_oracle_connection_details_extended(ctx, **kwargs):

    # create_oracle_connection read --ssh-key using --ssh-key-file
    if 'sshkey_file' in kwargs and kwargs['sshkey_file'] is not None:
        if kwargs.get('ssh_key') and kwargs.get('sshkey_file') is not None:
            raise cli_exceptions.RequiredValueNotInDefaultOrUserInputError('Cannot specify both --sshkey-file and --ssh-key.')
        sshkey_file = kwargs.get('sshkey_file')
        if sshkey_file:
            kwargs['ssh_key'] = sshkey_file.read()
    kwargs.pop('sshkey_file')

    if 'wallet' in kwargs and kwargs.get('wallet') is not None:
        # if --wallet is a file, else it should be a base64 encoded string.
        if os.path.exists(kwargs['wallet']) and os.path.isfile(kwargs['wallet']):
            try:
                binary_wallet_file = open(kwargs['wallet'], 'rb')
                kwargs['wallet'] = base64.b64encode(binary_wallet_file.read()).decode('utf-8')
            except Exception as e:
                raise click.ClickException(str(e))

    ctx.invoke(databasemigration_cli.create_connection_create_oracle_connection_details, **kwargs)
