# coding: utf-8
# Copyright (c) 2016, 2026, Oracle and/or its affiliates.  All rights reserved.
# This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
# NOTE: This class is auto generated by OracleSDKGenerator. DO NOT EDIT. API Version: 20250531

from __future__ import print_function
import click
import oci  # noqa: F401
import six  # noqa: F401
import sys  # noqa: F401
from oci_cli.cli_root import cli
from oci_cli import cli_constants  # noqa: F401
from oci_cli import cli_util
from oci_cli import json_skeleton_utils
from oci_cli import custom_types  # noqa: F401
from oci_cli.aliasing import CommandGroupWithAlias


@cli.command(cli_util.override('iot.iot_root_group.command_name', 'iot'), cls=CommandGroupWithAlias, help=cli_util.override('iot.iot_root_group.help', """Use the Internet of Things (IoT) API to manage IoT domain groups, domains, and digital twin resources including models, adapters, instances, and relationships.
For more information, see [Internet of Things]."""), short_help=cli_util.override('iot.iot_root_group.short_help', """Internet of Things API"""))
@cli_util.help_option_group
def iot_root_group():
    pass


@click.command(cli_util.override('iot.iot_domain_group.command_name', 'iot-domain'), cls=CommandGroupWithAlias, help="""An IoT domain is an Oracle Cloud Infrastructure resource that provides a managed environment for organizing and managing digital twin resources, such as models, adapters, instances and relationships, within a compartment and IoT domain group.

To use any API operations, you must be authorized in an IAM policy. If you are not authorized, contact an administrator. If you are an administrator who needs to create policies to grant users access, see [Getting Started with Policies].""")
@cli_util.help_option_group
def iot_domain_group():
    pass


@click.command(cli_util.override('iot.digital_twin_relationship_group.command_name', 'digital-twin-relationship'), cls=CommandGroupWithAlias, help="""A digital twin relationship represents an association between two digital twin instances. It can include properties to describe the nature and context of the association within the IoT domain.

To use any API operations, you must be authorized in an IAM policy. If you are not authorized, contact an administrator. If you are an administrator who needs to create policies to grant users access, see [Getting Started with Policies].""")
@cli_util.help_option_group
def digital_twin_relationship_group():
    pass


@click.command(cli_util.override('iot.digital_twin_model_group.command_name', 'digital-twin-model'), cls=CommandGroupWithAlias, help="""A digital twin model, defined using [Digital Twins Definition Language], specifies the schema for digital twin instance, including its components, properties, telemetry, commands, and relationships within the IoT domain.

To use any API operations, you must be authorized in an IAM policy. If you are not authorized, contact an administrator. If you are an administrator who needs to create policies to grant users access, see [Getting Started with Policies].""")
@cli_util.help_option_group
def digital_twin_model_group():
    pass


@click.command(cli_util.override('iot.iot_domain_group_group.command_name', 'iot-domain-group'), cls=CommandGroupWithAlias, help="""An IoT domain group is an Oracle Cloud Infrastructure resource that provides a managed environment for organizing and managing IoT domains, within a compartment.

To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see [Getting Started with Policies].""")
@cli_util.help_option_group
def iot_domain_group_group():
    pass


@click.command(cli_util.override('iot.digital_twin_adapter_group.command_name', 'digital-twin-adapter'), cls=CommandGroupWithAlias, help="""The digital twin adapter maps incoming data from IoT device into the corresponding digital twin instance. It defines the envelope structure, reference payload, routing and transformation rules using JSON Path and JQ to normalize the raw device data within the IoT domain.

To use any API operations, you must be authorized in an IAM policy. If you are not authorized, contact an administrator. If you are an administrator who needs to create policies to grant users access, see [Getting Started with Policies].""")
@cli_util.help_option_group
def digital_twin_adapter_group():
    pass


@click.command(cli_util.override('iot.work_request_group.command_name', 'work-request'), cls=CommandGroupWithAlias, help="""An asynchronous work request helps monitor long-running operations. When you initiate a long-running operation, the service creates a work request. This work request acts as an activity log, allowing you to track each step of the operation\u2019s progress. Each work request has an OCID, enabling programmatic interaction and automation.""")
@cli_util.help_option_group
def work_request_group():
    pass


@click.command(cli_util.override('iot.digital_twin_instance_group.command_name', 'digital-twin-instance'), cls=CommandGroupWithAlias, help="""A digital twin instance is a virtual representation of a physical IoT device within the IoT domain.

To use any API operations, you must be authorized in an IAM policy. If you are not authorized, contact an administrator. If you are an administrator who needs to create policies to grant users access, see [Getting Started with Policies].""")
@cli_util.help_option_group
def digital_twin_instance_group():
    pass


iot_root_group.add_command(iot_domain_group)
iot_root_group.add_command(digital_twin_relationship_group)
iot_root_group.add_command(digital_twin_model_group)
iot_root_group.add_command(iot_domain_group_group)
iot_root_group.add_command(digital_twin_adapter_group)
iot_root_group.add_command(work_request_group)
iot_root_group.add_command(digital_twin_instance_group)


@iot_domain_group.command(name=cli_util.override('iot.change_iot_domain_compartment.command_name', 'change-compartment'), help=u"""Moves an IoT domain to a different compartment within the same tenancy. For information about moving resources between compartments, see [Moving Resources to a Different Compartment]. \n[Command Reference](changeIotDomainCompartment)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--compartment-id', required=True, help=u"""The [OCID] of the compartment corresponding to the resource.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def change_iot_domain_compartment(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, compartment_id, if_match):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['compartmentId'] = compartment_id

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.change_iot_domain_compartment(
        iot_domain_id=iot_domain_id,
        change_iot_domain_compartment_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.change_iot_domain_data_retention_period.command_name', 'change-iot-domain-data-retention-period'), help=u"""Updates Data Retention Period of the IoT Domain. \n[Command Reference](changeIotDomainDataRetentionPeriod)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--type', required=True, type=custom_types.CliCaseInsensitiveChoice(["RAW_DATA", "REJECTED_DATA", "HISTORIZED_DATA", "RAW_COMMAND_DATA"]), help=u"""The type of data retention period to apply. Allowed values are RAW_DATA, REJECTED_DATA, HISTORIZED_DATA, and RAW_COMMAND_DATA.""")
@cli_util.option('--data-retention-period-in-days', required=True, type=click.INT, help=u"""The duration (in days) for which data will be retained in the IoT domain.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def change_iot_domain_data_retention_period(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, type, data_retention_period_in_days, if_match):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['type'] = type
    _details['dataRetentionPeriodInDays'] = data_retention_period_in_days

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.change_iot_domain_data_retention_period(
        iot_domain_id=iot_domain_id,
        change_iot_domain_data_retention_period_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group_group.command(name=cli_util.override('iot.change_iot_domain_group_compartment.command_name', 'change-compartment'), help=u"""Moves an IoT domain group to a different compartment within the same tenancy. For information about moving resources between compartments, see [Moving Resources to a Different Compartment]. \n[Command Reference](changeIotDomainGroupCompartment)""")
@cli_util.option('--iot-domain-group-id', required=True, help=u"""The [OCID] of an IoT Domain Group.""")
@cli_util.option('--compartment-id', required=True, help=u"""The [OCID] of the compartment corresponding to the resource.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def change_iot_domain_group_compartment(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_group_id, compartment_id, if_match):

    if isinstance(iot_domain_group_id, six.string_types) and len(iot_domain_group_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-group-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['compartmentId'] = compartment_id

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.change_iot_domain_group_compartment(
        iot_domain_group_id=iot_domain_group_id,
        change_iot_domain_group_compartment_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.configure_iot_domain_data_access.command_name', 'configure-iot-domain-data-access'), help=u"""Updates an IoT domain Data Access. \n[Command Reference](configureIotDomainDataAccess)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--type', required=True, type=custom_types.CliCaseInsensitiveChoice(["DIRECT", "ORDS", "APEX"]), help=u"""configuration type""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def configure_iot_domain_data_access(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, type, if_match):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['type'] = type

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.configure_iot_domain_data_access(
        iot_domain_id=iot_domain_id,
        configure_iot_domain_data_access_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.configure_iot_domain_data_access_apex_data_access_details.command_name', 'configure-iot-domain-data-access-apex-data-access-details'), help=u"""Updates an IoT domain Data Access. \n[Command Reference](configureIotDomainDataAccess)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--db-workspace-admin-initial-password', required=True, help=u"""Initial admin password for APEX workspace associated with the IoT domain.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def configure_iot_domain_data_access_apex_data_access_details(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, db_workspace_admin_initial_password, if_match):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['dbWorkspaceAdminInitialPassword'] = db_workspace_admin_initial_password

    _details['type'] = 'APEX'

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.configure_iot_domain_data_access(
        iot_domain_id=iot_domain_id,
        configure_iot_domain_data_access_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.configure_iot_domain_data_access_direct_data_access_details.command_name', 'configure-iot-domain-data-access-direct-data-access-details'), help=u"""Updates an IoT domain Data Access. \n[Command Reference](configureIotDomainDataAccess)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--db-allow-listed-identity-group-names', required=True, type=custom_types.CLI_COMPLEX_TYPE, help=u"""List of IAM groups of form described in [here] that are allowed to directly connect to the data host.""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'db-allow-listed-identity-group-names': {'module': 'iot', 'class': 'list[string]'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'db-allow-listed-identity-group-names': {'module': 'iot', 'class': 'list[string]'}})
@cli_util.wrap_exceptions
def configure_iot_domain_data_access_direct_data_access_details(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, db_allow_listed_identity_group_names, if_match):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['dbAllowListedIdentityGroupNames'] = cli_util.parse_json_parameter("db_allow_listed_identity_group_names", db_allow_listed_identity_group_names)

    _details['type'] = 'DIRECT'

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.configure_iot_domain_data_access(
        iot_domain_id=iot_domain_id,
        configure_iot_domain_data_access_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.configure_iot_domain_data_access_ords_data_access_details.command_name', 'configure-iot-domain-data-access-ords-data-access-details'), help=u"""Updates an IoT domain Data Access. \n[Command Reference](configureIotDomainDataAccess)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--db-allowed-identity-domain-host', required=True, help=u"""Host name of identity domain that is used for authenticating connect to data host via ORDS.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def configure_iot_domain_data_access_ords_data_access_details(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, db_allowed_identity_domain_host, if_match):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['dbAllowedIdentityDomainHost'] = db_allowed_identity_domain_host

    _details['type'] = 'ORDS'

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.configure_iot_domain_data_access(
        iot_domain_id=iot_domain_id,
        configure_iot_domain_data_access_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group_group.command(name=cli_util.override('iot.configure_iot_domain_group_data_access.command_name', 'configure-iot-domain-group-data-access'), help=u"""Updates an IoT domain Group Data Access. \n[Command Reference](configureIotDomainGroupDataAccess)""")
@cli_util.option('--iot-domain-group-id', required=True, help=u"""The [OCID] of an IoT Domain Group.""")
@cli_util.option('--db-allow-listed-vcn-ids', required=True, type=custom_types.CLI_COMPLEX_TYPE, help=u"""This is an array of VCN OCID (virtual cloud network Oracle Cloud ID) that is allowed to connect the data host.""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'db-allow-listed-vcn-ids': {'module': 'iot', 'class': 'list[string]'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'db-allow-listed-vcn-ids': {'module': 'iot', 'class': 'list[string]'}})
@cli_util.wrap_exceptions
def configure_iot_domain_group_data_access(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_group_id, db_allow_listed_vcn_ids, if_match):

    if isinstance(iot_domain_group_id, six.string_types) and len(iot_domain_group_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-group-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['dbAllowListedVcnIds'] = cli_util.parse_json_parameter("db_allow_listed_vcn_ids", db_allow_listed_vcn_ids)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.configure_iot_domain_group_data_access(
        iot_domain_group_id=iot_domain_group_id,
        configure_iot_domain_group_data_access_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_adapter_group.command(name=cli_util.override('iot.create_digital_twin_adapter.command_name', 'create'), help=u"""Creates a new digital twin adapter. \n[Command Reference](createDigitalTwinAdapter)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--digital-twin-model-id', help=u"""The [OCID] of the digital twin model.""")
@cli_util.option('--digital-twin-model-spec-uri', help=u"""The URI of the digital twin model specification.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--inbound-envelope', type=custom_types.CLI_COMPLEX_TYPE, help=u"""""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--inbound-routes', type=custom_types.CLI_COMPLEX_TYPE, help=u"""list of inbound routes

This option is a JSON list with items of type DigitalTwinAdapterInboundRoute.  For documentation on DigitalTwinAdapterInboundRoute please see our API reference: https://docs.oracle.com/en-us/iaas/api/#/en/iot/20250531/datatypes/DigitalTwinAdapterInboundRoute.""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'inbound-envelope': {'module': 'iot', 'class': 'DigitalTwinAdapterInboundEnvelope'}, 'inbound-routes': {'module': 'iot', 'class': 'list[DigitalTwinAdapterInboundRoute]'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'inbound-envelope': {'module': 'iot', 'class': 'DigitalTwinAdapterInboundEnvelope'}, 'inbound-routes': {'module': 'iot', 'class': 'list[DigitalTwinAdapterInboundRoute]'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'DigitalTwinAdapter'})
@cli_util.wrap_exceptions
def create_digital_twin_adapter(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, digital_twin_model_id, digital_twin_model_spec_uri, display_name, description, inbound_envelope, inbound_routes, freeform_tags, defined_tags):

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['iotDomainId'] = iot_domain_id

    if digital_twin_model_id is not None:
        _details['digitalTwinModelId'] = digital_twin_model_id

    if digital_twin_model_spec_uri is not None:
        _details['digitalTwinModelSpecUri'] = digital_twin_model_spec_uri

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if inbound_envelope is not None:
        _details['inboundEnvelope'] = cli_util.parse_json_parameter("inbound_envelope", inbound_envelope)

    if inbound_routes is not None:
        _details['inboundRoutes'] = cli_util.parse_json_parameter("inbound_routes", inbound_routes)

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.create_digital_twin_adapter(
        create_digital_twin_adapter_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_adapter') and callable(getattr(client, 'get_digital_twin_adapter')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_digital_twin_adapter(result.data.id), 'lifecycle_state', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.create_digital_twin_instance.command_name', 'create'), help=u"""Creates a new digital twin instance. \n[Command Reference](createDigitalTwinInstance)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--connectivity-type', type=custom_types.CliCaseInsensitiveChoice(["DIRECT", "INDIRECT", "GATEWAY", "NONE"]), help=u"""Connectivity type of the digital twin instance""")
@cli_util.option('--auth-id', help=u"""The [OCID] of the resource (like VaultSecret, ClientCertificate etc.,) used to authenticate the digital twin instance.""")
@cli_util.option('--external-key', help=u"""A unique identifier for the physical entity (typically an IoT device) represented by the digital twin instance. This could be a Bluetooth address, Ethernet MAC address, or serial number, depending on the use case. If not provided, the system will automatically generate one.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--digital-twin-adapter-id', help=u"""The [OCID] of the digital twin adapter.""")
@cli_util.option('--digital-twin-model-id', help=u"""The [OCID] of the digital twin model.""")
@cli_util.option('--digital-twin-model-spec-uri', help=u"""The URI of the digital twin model specification.""")
@cli_util.option('--gateways', type=custom_types.CLI_COMPLEX_TYPE, help=u"""An array of unique ids ([OCIDs]) of the IoT digital twin instances with connectivityType equals to GATEWAY.""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'gateways': {'module': 'iot', 'class': 'list[string]'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'gateways': {'module': 'iot', 'class': 'list[string]'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'DigitalTwinInstance'})
@cli_util.wrap_exceptions
def create_digital_twin_instance(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, connectivity_type, auth_id, external_key, display_name, description, digital_twin_adapter_id, digital_twin_model_id, digital_twin_model_spec_uri, gateways, freeform_tags, defined_tags):

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['iotDomainId'] = iot_domain_id

    if connectivity_type is not None:
        _details['connectivityType'] = connectivity_type

    if auth_id is not None:
        _details['authId'] = auth_id

    if external_key is not None:
        _details['externalKey'] = external_key

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if digital_twin_adapter_id is not None:
        _details['digitalTwinAdapterId'] = digital_twin_adapter_id

    if digital_twin_model_id is not None:
        _details['digitalTwinModelId'] = digital_twin_model_id

    if digital_twin_model_spec_uri is not None:
        _details['digitalTwinModelSpecUri'] = digital_twin_model_spec_uri

    if gateways is not None:
        _details['gateways'] = cli_util.parse_json_parameter("gateways", gateways)

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.create_digital_twin_instance(
        create_digital_twin_instance_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_instance') and callable(getattr(client, 'get_digital_twin_instance')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_digital_twin_instance(result.data.id), 'lifecycle_state', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_model_group.command(name=cli_util.override('iot.create_digital_twin_model.command_name', 'create'), help=u"""Creates a new digital twin model. \n[Command Reference](createDigitalTwinModel)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--spec', required=True, type=custom_types.CLI_COMPLEX_TYPE, help=u"""The specification of the digital twin model (DTDL).""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. If left blank, the display name will be derived from the spec.""")
@cli_util.option('--description', help=u"""A short description of the resource. If left blank, the description will be derived from the spec.""")
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'spec': {'module': 'iot', 'class': 'dict(str, object)'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'spec': {'module': 'iot', 'class': 'dict(str, object)'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'DigitalTwinModel'})
@cli_util.wrap_exceptions
def create_digital_twin_model(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, spec, display_name, description, freeform_tags, defined_tags):

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['iotDomainId'] = iot_domain_id
    _details['spec'] = cli_util.parse_json_parameter("spec", spec)

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.create_digital_twin_model(
        create_digital_twin_model_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_model') and callable(getattr(client, 'get_digital_twin_model')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_digital_twin_model(result.data.id), 'lifecycle_state', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_relationship_group.command(name=cli_util.override('iot.create_digital_twin_relationship.command_name', 'create'), help=u"""Creates a new digital twin relationship. \n[Command Reference](createDigitalTwinRelationship)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--content-path', required=True, help=u"""Its the name of the relationship that links two digital twin instances. Here, it is the relationship name of the source digital twin model.""")
@cli_util.option('--source-digital-twin-instance-id', required=True, help=u"""The [OCID] of source digital twin instance.""")
@cli_util.option('--target-digital-twin-instance-id', required=True, help=u"""The [OCID] of target digital twin instance.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--content', type=custom_types.CLI_COMPLEX_TYPE, help=u"""The value(s) of the relationship properties defined in the source digital twin model.""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'content': {'module': 'iot', 'class': 'dict(str, object)'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'content': {'module': 'iot', 'class': 'dict(str, object)'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'DigitalTwinRelationship'})
@cli_util.wrap_exceptions
def create_digital_twin_relationship(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, content_path, source_digital_twin_instance_id, target_digital_twin_instance_id, display_name, description, content, freeform_tags, defined_tags):

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['iotDomainId'] = iot_domain_id
    _details['contentPath'] = content_path
    _details['sourceDigitalTwinInstanceId'] = source_digital_twin_instance_id
    _details['targetDigitalTwinInstanceId'] = target_digital_twin_instance_id

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if content is not None:
        _details['content'] = cli_util.parse_json_parameter("content", content)

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.create_digital_twin_relationship(
        create_digital_twin_relationship_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_relationship') and callable(getattr(client, 'get_digital_twin_relationship')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_digital_twin_relationship(result.data.id), 'lifecycle_state', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.create_iot_domain.command_name', 'create'), help=u"""Creates a new IoT domain. \n[Command Reference](createIotDomain)""")
@cli_util.option('--iot-domain-group-id', required=True, help=u"""The [OCID] of the IoT domain group.""")
@cli_util.option('--compartment-id', required=True, help=u"""The [OCID] of the compartment corresponding to the resource.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'IotDomain'})
@cli_util.wrap_exceptions
def create_iot_domain(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_group_id, compartment_id, display_name, description, freeform_tags, defined_tags):

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['iotDomainGroupId'] = iot_domain_group_id
    _details['compartmentId'] = compartment_id

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.create_iot_domain(
        create_iot_domain_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group_group.command(name=cli_util.override('iot.create_iot_domain_group.command_name', 'create'), help=u"""Creates a new IoT domain group. \n[Command Reference](createIotDomainGroup)""")
@cli_util.option('--compartment-id', required=True, help=u"""The [OCID] of the compartment corresponding to the resource.""")
@cli_util.option('--type', type=custom_types.CliCaseInsensitiveChoice(["PRODUCTION", "DEVELOPMENT", "STANDARD", "LIGHTWEIGHT"]), help=u"""Type of domain group. DEVELOPMENT uses fewer resources and has a higher Recovery Time Objective (RTO), making it suitable for development and testing. PRODUCTION is recommended for production workloads. LIGHTWEIGHT and STANDARD are deprecated aliases for DEVELOPMENT and PRODUCTION respectively and will be removed in a future release.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'IotDomainGroup'})
@cli_util.wrap_exceptions
def create_iot_domain_group(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, compartment_id, type, display_name, description, freeform_tags, defined_tags):

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['compartmentId'] = compartment_id

    if type is not None:
        _details['type'] = type

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.create_iot_domain_group(
        create_iot_domain_group_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_adapter_group.command(name=cli_util.override('iot.delete_digital_twin_adapter.command_name', 'delete'), help=u"""Deletes the digital twin adapter identified by the specified OCID. \n[Command Reference](deleteDigitalTwinAdapter)""")
@cli_util.option('--digital-twin-adapter-id', required=True, help=u"""The [OCID] of the digital twin adapter.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.confirm_delete_option
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def delete_digital_twin_adapter(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, digital_twin_adapter_id, if_match):

    if isinstance(digital_twin_adapter_id, six.string_types) and len(digital_twin_adapter_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-adapter-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.delete_digital_twin_adapter(
        digital_twin_adapter_id=digital_twin_adapter_id,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_adapter') and callable(getattr(client, 'get_digital_twin_adapter')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                oci.wait_until(client, client.get_digital_twin_adapter(digital_twin_adapter_id), 'lifecycle_state', wait_for_state, succeed_on_not_found=True, **wait_period_kwargs)
            except oci.exceptions.ServiceError as e:
                # We make an initial service call so we can pass the result to oci.wait_until(), however if we are waiting on the
                # outcome of a delete operation it is possible that the resource is already gone and so the initial service call
                # will result in an exception that reflects a HTTP 404. In this case, we can exit with success (rather than raising
                # the exception) since this would have been the behaviour in the waiter anyway (as for delete we provide the argument
                # succeed_on_not_found=True to the waiter).
                #
                # Any non-404 should still result in the exception being thrown.
                if e.status == 404:
                    pass
                else:
                    raise
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Please retrieve the resource to find its current state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.delete_digital_twin_instance.command_name', 'delete'), help=u"""Deletes the digital twin instance identified by the specified OCID. \n[Command Reference](deleteDigitalTwinInstance)""")
@cli_util.option('--digital-twin-instance-id', required=True, help=u"""The [OCID] of digital twin instance.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.confirm_delete_option
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def delete_digital_twin_instance(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, digital_twin_instance_id, if_match):

    if isinstance(digital_twin_instance_id, six.string_types) and len(digital_twin_instance_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-instance-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.delete_digital_twin_instance(
        digital_twin_instance_id=digital_twin_instance_id,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_instance') and callable(getattr(client, 'get_digital_twin_instance')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                oci.wait_until(client, client.get_digital_twin_instance(digital_twin_instance_id), 'lifecycle_state', wait_for_state, succeed_on_not_found=True, **wait_period_kwargs)
            except oci.exceptions.ServiceError as e:
                # We make an initial service call so we can pass the result to oci.wait_until(), however if we are waiting on the
                # outcome of a delete operation it is possible that the resource is already gone and so the initial service call
                # will result in an exception that reflects a HTTP 404. In this case, we can exit with success (rather than raising
                # the exception) since this would have been the behaviour in the waiter anyway (as for delete we provide the argument
                # succeed_on_not_found=True to the waiter).
                #
                # Any non-404 should still result in the exception being thrown.
                if e.status == 404:
                    pass
                else:
                    raise
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Please retrieve the resource to find its current state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_model_group.command(name=cli_util.override('iot.delete_digital_twin_model.command_name', 'delete'), help=u"""Deletes the digital twin model identified by the specified OCID. \n[Command Reference](deleteDigitalTwinModel)""")
@cli_util.option('--digital-twin-model-id', required=True, help=u"""The [OCID] of digital twin model.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.confirm_delete_option
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def delete_digital_twin_model(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, digital_twin_model_id, if_match):

    if isinstance(digital_twin_model_id, six.string_types) and len(digital_twin_model_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-model-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.delete_digital_twin_model(
        digital_twin_model_id=digital_twin_model_id,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_model') and callable(getattr(client, 'get_digital_twin_model')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                oci.wait_until(client, client.get_digital_twin_model(digital_twin_model_id), 'lifecycle_state', wait_for_state, succeed_on_not_found=True, **wait_period_kwargs)
            except oci.exceptions.ServiceError as e:
                # We make an initial service call so we can pass the result to oci.wait_until(), however if we are waiting on the
                # outcome of a delete operation it is possible that the resource is already gone and so the initial service call
                # will result in an exception that reflects a HTTP 404. In this case, we can exit with success (rather than raising
                # the exception) since this would have been the behaviour in the waiter anyway (as for delete we provide the argument
                # succeed_on_not_found=True to the waiter).
                #
                # Any non-404 should still result in the exception being thrown.
                if e.status == 404:
                    pass
                else:
                    raise
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Please retrieve the resource to find its current state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_relationship_group.command(name=cli_util.override('iot.delete_digital_twin_relationship.command_name', 'delete'), help=u"""Deletes the digital twin relationship identified by the specified OCID. \n[Command Reference](deleteDigitalTwinRelationship)""")
@cli_util.option('--digital-twin-relationship-id', required=True, help=u"""The [OCID] of digital twin relationship.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.confirm_delete_option
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def delete_digital_twin_relationship(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, digital_twin_relationship_id, if_match):

    if isinstance(digital_twin_relationship_id, six.string_types) and len(digital_twin_relationship_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-relationship-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.delete_digital_twin_relationship(
        digital_twin_relationship_id=digital_twin_relationship_id,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_relationship') and callable(getattr(client, 'get_digital_twin_relationship')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                oci.wait_until(client, client.get_digital_twin_relationship(digital_twin_relationship_id), 'lifecycle_state', wait_for_state, succeed_on_not_found=True, **wait_period_kwargs)
            except oci.exceptions.ServiceError as e:
                # We make an initial service call so we can pass the result to oci.wait_until(), however if we are waiting on the
                # outcome of a delete operation it is possible that the resource is already gone and so the initial service call
                # will result in an exception that reflects a HTTP 404. In this case, we can exit with success (rather than raising
                # the exception) since this would have been the behaviour in the waiter anyway (as for delete we provide the argument
                # succeed_on_not_found=True to the waiter).
                #
                # Any non-404 should still result in the exception being thrown.
                if e.status == 404:
                    pass
                else:
                    raise
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Please retrieve the resource to find its current state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.delete_iot_domain.command_name', 'delete'), help=u"""Deletes the IoT domain identified by the specified OCID. \n[Command Reference](deleteIotDomain)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.confirm_delete_option
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def delete_iot_domain(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, if_match):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.delete_iot_domain(
        iot_domain_id=iot_domain_id,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Please retrieve the work request to find its current state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group_group.command(name=cli_util.override('iot.delete_iot_domain_group.command_name', 'delete'), help=u"""Deletes the IoT domain group identified by the specified OCID. \n[Command Reference](deleteIotDomainGroup)""")
@cli_util.option('--iot-domain-group-id', required=True, help=u"""The [OCID] of an IoT Domain Group.""")
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.confirm_delete_option
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def delete_iot_domain_group(ctx, from_json, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_group_id, if_match):

    if isinstance(iot_domain_group_id, six.string_types) and len(iot_domain_group_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-group-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.delete_iot_domain_group(
        iot_domain_group_id=iot_domain_group_id,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Please retrieve the work request to find its current state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_adapter_group.command(name=cli_util.override('iot.get_digital_twin_adapter.command_name', 'get'), help=u"""Retrieves the digital twin adapter identified by the specified OCID. \n[Command Reference](getDigitalTwinAdapter)""")
@cli_util.option('--digital-twin-adapter-id', required=True, help=u"""The [OCID] of the digital twin adapter.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'DigitalTwinAdapter'})
@cli_util.wrap_exceptions
def get_digital_twin_adapter(ctx, from_json, digital_twin_adapter_id):

    if isinstance(digital_twin_adapter_id, six.string_types) and len(digital_twin_adapter_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-adapter-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_digital_twin_adapter(
        digital_twin_adapter_id=digital_twin_adapter_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.get_digital_twin_instance.command_name', 'get'), help=u"""Retrieves the digital twin instance identified by the specified OCID. \n[Command Reference](getDigitalTwinInstance)""")
@cli_util.option('--digital-twin-instance-id', required=True, help=u"""The [OCID] of digital twin instance.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'DigitalTwinInstance'})
@cli_util.wrap_exceptions
def get_digital_twin_instance(ctx, from_json, digital_twin_instance_id):

    if isinstance(digital_twin_instance_id, six.string_types) and len(digital_twin_instance_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-instance-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_digital_twin_instance(
        digital_twin_instance_id=digital_twin_instance_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.get_digital_twin_instance_content.command_name', 'get-digital-twin-instance-content'), help=u"""Retrieves the content associated with a digital twin instance identified by the specified OCID. The content can be retrieved only when a model is associated with the digital twin instance. \n[Command Reference](getDigitalTwinInstanceContent)""")
@cli_util.option('--digital-twin-instance-id', required=True, help=u"""The [OCID] of digital twin instance.""")
@cli_util.option('--should-include-metadata', type=click.BOOL, help=u"""If set to true , digital twin instance metadata is included in the response.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def get_digital_twin_instance_content(ctx, from_json, digital_twin_instance_id, should_include_metadata):

    if isinstance(digital_twin_instance_id, six.string_types) and len(digital_twin_instance_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-instance-id cannot be whitespace or empty string')

    kwargs = {}
    if should_include_metadata is not None:
        kwargs['should_include_metadata'] = should_include_metadata
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_digital_twin_instance_content(
        digital_twin_instance_id=digital_twin_instance_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_model_group.command(name=cli_util.override('iot.get_digital_twin_model.command_name', 'get'), help=u"""Retrieves the digital twin model identified by the specified OCID. \n[Command Reference](getDigitalTwinModel)""")
@cli_util.option('--digital-twin-model-id', required=True, help=u"""The [OCID] of digital twin model.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'DigitalTwinModel'})
@cli_util.wrap_exceptions
def get_digital_twin_model(ctx, from_json, digital_twin_model_id):

    if isinstance(digital_twin_model_id, six.string_types) and len(digital_twin_model_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-model-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_digital_twin_model(
        digital_twin_model_id=digital_twin_model_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_model_group.command(name=cli_util.override('iot.get_digital_twin_model_spec.command_name', 'get-digital-twin-model-spec'), help=u"""Retrieves the spec of digital twin model identified by the specified OCID. \n[Command Reference](getDigitalTwinModelSpec)""")
@cli_util.option('--digital-twin-model-id', required=True, help=u"""The [OCID] of digital twin model.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def get_digital_twin_model_spec(ctx, from_json, digital_twin_model_id):

    if isinstance(digital_twin_model_id, six.string_types) and len(digital_twin_model_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-model-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_digital_twin_model_spec(
        digital_twin_model_id=digital_twin_model_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_relationship_group.command(name=cli_util.override('iot.get_digital_twin_relationship.command_name', 'get'), help=u"""Retrieves the digital twin relationship identified by the specified OCID. \n[Command Reference](getDigitalTwinRelationship)""")
@cli_util.option('--digital-twin-relationship-id', required=True, help=u"""The [OCID] of digital twin relationship.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'DigitalTwinRelationship'})
@cli_util.wrap_exceptions
def get_digital_twin_relationship(ctx, from_json, digital_twin_relationship_id):

    if isinstance(digital_twin_relationship_id, six.string_types) and len(digital_twin_relationship_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-relationship-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_digital_twin_relationship(
        digital_twin_relationship_id=digital_twin_relationship_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.get_iot_domain.command_name', 'get'), help=u"""Retrieves the IoT domain identified by the specified OCID. \n[Command Reference](getIotDomain)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'IotDomain'})
@cli_util.wrap_exceptions
def get_iot_domain(ctx, from_json, iot_domain_id):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_iot_domain(
        iot_domain_id=iot_domain_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@iot_domain_group_group.command(name=cli_util.override('iot.get_iot_domain_group.command_name', 'get'), help=u"""Retrieves the IoT domain group identified by the specified OCID. \n[Command Reference](getIotDomainGroup)""")
@cli_util.option('--iot-domain-group-id', required=True, help=u"""The [OCID] of an IoT Domain Group.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'IotDomainGroup'})
@cli_util.wrap_exceptions
def get_iot_domain_group(ctx, from_json, iot_domain_group_id):

    if isinstance(iot_domain_group_id, six.string_types) and len(iot_domain_group_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-group-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_iot_domain_group(
        iot_domain_group_id=iot_domain_group_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@work_request_group.command(name=cli_util.override('iot.get_work_request.command_name', 'get'), help=u"""Retrieves the status of the work request with the given ID. \n[Command Reference](getWorkRequest)""")
@cli_util.option('--work-request-id', required=True, help=u"""The [OCID] of the asynchronous work request.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'WorkRequest'})
@cli_util.wrap_exceptions
def get_work_request(ctx, from_json, work_request_id):

    if isinstance(work_request_id, six.string_types) and len(work_request_id.strip()) == 0:
        raise click.UsageError('Parameter --work-request-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.get_work_request(
        work_request_id=work_request_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.invoke_raw_command.command_name', 'invoke-raw-command'), help=u"""Invokes the raw command on the specified digital twin instance. \n[Command Reference](invokeRawCommand)""")
@cli_util.option('--digital-twin-instance-id', required=True, help=u"""The [OCID] of digital twin instance.""")
@cli_util.option('--request-endpoint', required=True, help=u"""Device endpoint where request should be forwarded to.""")
@cli_util.option('--request-data-format', required=True, type=custom_types.CliCaseInsensitiveChoice(["TEXT", "JSON", "BINARY"]), help=u"""data format: json, binary, text""")
@cli_util.option('--request-duration', help=u"""Specified duration by which to send the request by.""")
@cli_util.option('--response-duration', help=u"""Specified duration by which to receive the response by.""")
@cli_util.option('--response-endpoint', help=u"""Device endpoint from which response is expected to come.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def invoke_raw_command(ctx, from_json, digital_twin_instance_id, request_endpoint, request_data_format, request_duration, response_duration, response_endpoint):

    if isinstance(digital_twin_instance_id, six.string_types) and len(digital_twin_instance_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-instance-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['requestEndpoint'] = request_endpoint
    _details['requestDataFormat'] = request_data_format

    if request_duration is not None:
        _details['requestDuration'] = request_duration

    if response_duration is not None:
        _details['responseDuration'] = response_duration

    if response_endpoint is not None:
        _details['responseEndpoint'] = response_endpoint

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.invoke_raw_command(
        digital_twin_instance_id=digital_twin_instance_id,
        invoke_raw_command_details=_details,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.invoke_raw_command_invoke_raw_binary_command_details.command_name', 'invoke-raw-command-invoke-raw-binary-command-details'), help=u"""Invokes the raw command on the specified digital twin instance. \n[Command Reference](invokeRawCommand)""")
@cli_util.option('--digital-twin-instance-id', required=True, help=u"""The [OCID] of digital twin instance.""")
@cli_util.option('--request-endpoint', required=True, help=u"""Device endpoint where request should be forwarded to.""")
@cli_util.option('--request-duration', help=u"""Specified duration by which to send the request by.""")
@cli_util.option('--response-duration', help=u"""Specified duration by which to receive the response by.""")
@cli_util.option('--response-endpoint', help=u"""Device endpoint from which response is expected to come.""")
@cli_util.option('--request-data-content-type', help=u"""Mime content type of data encoded using base64, default is application/octet-stream""")
@cli_util.option('--request-data', help=u"""base 64 encoded request data""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def invoke_raw_command_invoke_raw_binary_command_details(ctx, from_json, digital_twin_instance_id, request_endpoint, request_duration, response_duration, response_endpoint, request_data_content_type, request_data):

    if isinstance(digital_twin_instance_id, six.string_types) and len(digital_twin_instance_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-instance-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['requestEndpoint'] = request_endpoint

    if request_duration is not None:
        _details['requestDuration'] = request_duration

    if response_duration is not None:
        _details['responseDuration'] = response_duration

    if response_endpoint is not None:
        _details['responseEndpoint'] = response_endpoint

    if request_data_content_type is not None:
        _details['requestDataContentType'] = request_data_content_type

    if request_data is not None:
        _details['requestData'] = request_data

    _details['requestDataFormat'] = 'BINARY'

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.invoke_raw_command(
        digital_twin_instance_id=digital_twin_instance_id,
        invoke_raw_command_details=_details,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.invoke_raw_command_invoke_raw_text_command_details.command_name', 'invoke-raw-command-invoke-raw-text-command-details'), help=u"""Invokes the raw command on the specified digital twin instance. \n[Command Reference](invokeRawCommand)""")
@cli_util.option('--digital-twin-instance-id', required=True, help=u"""The [OCID] of digital twin instance.""")
@cli_util.option('--request-endpoint', required=True, help=u"""Device endpoint where request should be forwarded to.""")
@cli_util.option('--request-duration', help=u"""Specified duration by which to send the request by.""")
@cli_util.option('--response-duration', help=u"""Specified duration by which to receive the response by.""")
@cli_util.option('--response-endpoint', help=u"""Device endpoint from which response is expected to come.""")
@cli_util.option('--request-data-content-type', help=u"""Mime content type of text data, default is text/plain""")
@cli_util.option('--request-data', help=u"""Plain text request data""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={})
@cli_util.wrap_exceptions
def invoke_raw_command_invoke_raw_text_command_details(ctx, from_json, digital_twin_instance_id, request_endpoint, request_duration, response_duration, response_endpoint, request_data_content_type, request_data):

    if isinstance(digital_twin_instance_id, six.string_types) and len(digital_twin_instance_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-instance-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['requestEndpoint'] = request_endpoint

    if request_duration is not None:
        _details['requestDuration'] = request_duration

    if response_duration is not None:
        _details['responseDuration'] = response_duration

    if response_endpoint is not None:
        _details['responseEndpoint'] = response_endpoint

    if request_data_content_type is not None:
        _details['requestDataContentType'] = request_data_content_type

    if request_data is not None:
        _details['requestData'] = request_data

    _details['requestDataFormat'] = 'TEXT'

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.invoke_raw_command(
        digital_twin_instance_id=digital_twin_instance_id,
        invoke_raw_command_details=_details,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.invoke_raw_command_invoke_raw_json_command_details.command_name', 'invoke-raw-command-invoke-raw-json-command-details'), help=u"""Invokes the raw command on the specified digital twin instance. \n[Command Reference](invokeRawCommand)""")
@cli_util.option('--digital-twin-instance-id', required=True, help=u"""The [OCID] of digital twin instance.""")
@cli_util.option('--request-endpoint', required=True, help=u"""Device endpoint where request should be forwarded to.""")
@cli_util.option('--request-duration', help=u"""Specified duration by which to send the request by.""")
@cli_util.option('--response-duration', help=u"""Specified duration by which to receive the response by.""")
@cli_util.option('--response-endpoint', help=u"""Device endpoint from which response is expected to come.""")
@cli_util.option('--request-data-content-type', help=u"""Mime content type of json data, default is application/json""")
@cli_util.option('--request-data', type=custom_types.CLI_COMPLEX_TYPE, help=u"""request data, maximum 256k""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@json_skeleton_utils.get_cli_json_input_option({'request-data': {'module': 'iot', 'class': 'dict(str, object)'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'request-data': {'module': 'iot', 'class': 'dict(str, object)'}})
@cli_util.wrap_exceptions
def invoke_raw_command_invoke_raw_json_command_details(ctx, from_json, digital_twin_instance_id, request_endpoint, request_duration, response_duration, response_endpoint, request_data_content_type, request_data):

    if isinstance(digital_twin_instance_id, six.string_types) and len(digital_twin_instance_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-instance-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['requestEndpoint'] = request_endpoint

    if request_duration is not None:
        _details['requestDuration'] = request_duration

    if response_duration is not None:
        _details['responseDuration'] = response_duration

    if response_endpoint is not None:
        _details['responseEndpoint'] = response_endpoint

    if request_data_content_type is not None:
        _details['requestDataContentType'] = request_data_content_type

    if request_data is not None:
        _details['requestData'] = cli_util.parse_json_parameter("request_data", request_data)

    _details['requestDataFormat'] = 'JSON'

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.invoke_raw_command(
        digital_twin_instance_id=digital_twin_instance_id,
        invoke_raw_command_details=_details,
        **kwargs
    )
    cli_util.render_response(result, ctx)


@digital_twin_adapter_group.command(name=cli_util.override('iot.list_digital_twin_adapters.command_name', 'list'), help=u"""Retrieves a list of digital twin adapters within the specified IoT domain. \n[Command Reference](listDigitalTwinAdapters)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain in which to list digital twin resources.""")
@cli_util.option('--id', help=u"""Filter resources by [OCID]. Must be a valid OCID of the resource type.""")
@cli_util.option('--digital-twin-model-spec-uri', help=u"""Filter resources that match the specified URI (DTMI) of the digital twin model.""")
@cli_util.option('--digital-twin-model-id', help=u"""Filter resources that match the specified [OCID] of the digital twin model.""")
@cli_util.option('--display-name', help=u"""Filter resources whose display name matches the specified value.""")
@cli_util.option('--lifecycle-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), help=u"""Filter resources whose lifecycleState matches the specified value.""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--page', help=u"""Page representing the requested page of items.""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeCreated", "displayName"]), help=u"""The field to sort by. Only one sort order may be provided. Default order for timeCreated is descending. Default order for displayName is ascending.""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'DigitalTwinAdapterCollection'})
@cli_util.wrap_exceptions
def list_digital_twin_adapters(ctx, from_json, all_pages, page_size, iot_domain_id, id, digital_twin_model_spec_uri, digital_twin_model_id, display_name, lifecycle_state, limit, page, sort_order, sort_by):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    kwargs = {}
    if id is not None:
        kwargs['id'] = id
    if digital_twin_model_spec_uri is not None:
        kwargs['digital_twin_model_spec_uri'] = digital_twin_model_spec_uri
    if digital_twin_model_id is not None:
        kwargs['digital_twin_model_id'] = digital_twin_model_id
    if display_name is not None:
        kwargs['display_name'] = display_name
    if lifecycle_state is not None:
        kwargs['lifecycle_state'] = lifecycle_state
    if limit is not None:
        kwargs['limit'] = limit
    if page is not None:
        kwargs['page'] = page
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_digital_twin_adapters,
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_digital_twin_adapters,
            limit,
            page_size,
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    else:
        result = client.list_digital_twin_adapters(
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.list_digital_twin_instances.command_name', 'list'), help=u"""Retrieves a list of digital twin instances within the specified IoT domain. \n[Command Reference](listDigitalTwinInstances)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain in which to list digital twin resources.""")
@cli_util.option('--display-name', help=u"""Filter resources whose display name matches the specified value.""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--page', help=u"""Page representing the requested page of items.""")
@cli_util.option('--lifecycle-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), help=u"""Filter resources whose lifecycleState matches the specified value.""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeCreated", "displayName"]), help=u"""The field to sort by. Only one sort order may be provided. Default order for timeCreated is descending. Default order for displayName is ascending.""")
@cli_util.option('--digital-twin-model-id', help=u"""Filter resources that match the specified [OCID] of the digital twin model.""")
@cli_util.option('--digital-twin-model-spec-uri', help=u"""Filter resources that match the specified URI (DTMI) of the digital twin model.""")
@cli_util.option('--connectivity-type', type=custom_types.CliCaseInsensitiveChoice(["DIRECT", "INDIRECT", "GATEWAY", "NONE"]), help=u"""Filter resources whose connectivityType matches the specified value.""")
@cli_util.option('--id', help=u"""Filter resources by [OCID]. Must be a valid OCID of the resource type.""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'DigitalTwinInstanceCollection'})
@cli_util.wrap_exceptions
def list_digital_twin_instances(ctx, from_json, all_pages, page_size, iot_domain_id, display_name, limit, page, lifecycle_state, sort_order, sort_by, digital_twin_model_id, digital_twin_model_spec_uri, connectivity_type, id):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    kwargs = {}
    if display_name is not None:
        kwargs['display_name'] = display_name
    if limit is not None:
        kwargs['limit'] = limit
    if page is not None:
        kwargs['page'] = page
    if lifecycle_state is not None:
        kwargs['lifecycle_state'] = lifecycle_state
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    if digital_twin_model_id is not None:
        kwargs['digital_twin_model_id'] = digital_twin_model_id
    if digital_twin_model_spec_uri is not None:
        kwargs['digital_twin_model_spec_uri'] = digital_twin_model_spec_uri
    if connectivity_type is not None:
        kwargs['connectivity_type'] = connectivity_type
    if id is not None:
        kwargs['id'] = id
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_digital_twin_instances,
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_digital_twin_instances,
            limit,
            page_size,
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    else:
        result = client.list_digital_twin_instances(
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@digital_twin_model_group.command(name=cli_util.override('iot.list_digital_twin_models.command_name', 'list'), help=u"""Retrieves a list of digital twin models within the specified IoT domain. \n[Command Reference](listDigitalTwinModels)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain in which to list digital twin resources.""")
@cli_util.option('--id', help=u"""Filter resources by [OCID]. Must be a valid OCID of the resource type.""")
@cli_util.option('--display-name', help=u"""Filter resources whose display name matches the specified value.""")
@cli_util.option('--spec-uri-starts-with', help=u"""Filters resources by spec URI prefix. For example, to search all versions of the `dtmi:example:device;1` model, pass the prefix without the version: `dtmi:example:device`.""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--page', help=u"""Page representing the requested page of items.""")
@cli_util.option('--lifecycle-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), help=u"""Filter resources whose lifecycleState matches the specified value.""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeCreated", "displayName"]), help=u"""The field to sort by. Only one sort order may be provided. Default order for timeCreated is descending. Default order for displayName is ascending.""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'DigitalTwinModelCollection'})
@cli_util.wrap_exceptions
def list_digital_twin_models(ctx, from_json, all_pages, page_size, iot_domain_id, id, display_name, spec_uri_starts_with, limit, page, lifecycle_state, sort_order, sort_by):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    kwargs = {}
    if id is not None:
        kwargs['id'] = id
    if display_name is not None:
        kwargs['display_name'] = display_name
    if spec_uri_starts_with is not None:
        kwargs['spec_uri_starts_with'] = spec_uri_starts_with
    if limit is not None:
        kwargs['limit'] = limit
    if page is not None:
        kwargs['page'] = page
    if lifecycle_state is not None:
        kwargs['lifecycle_state'] = lifecycle_state
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_digital_twin_models,
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_digital_twin_models,
            limit,
            page_size,
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    else:
        result = client.list_digital_twin_models(
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@digital_twin_relationship_group.command(name=cli_util.override('iot.list_digital_twin_relationships.command_name', 'list'), help=u"""Retrieves a list of digital twin relationships within the specified IoT domain. \n[Command Reference](listDigitalTwinRelationships)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain in which to list digital twin resources.""")
@cli_util.option('--display-name', help=u"""Filter resources whose display name matches the specified value.""")
@cli_util.option('--content-path', help=u"""Filters resources that match the content path of the digital twin relationship.""")
@cli_util.option('--source-digital-twin-instance-id', help=u"""Filter resources that match the specified [OCID] of source digital twin instance.""")
@cli_util.option('--target-digital-twin-instance-id', help=u"""Filter resources that match the specified [OCID] of target digital twin instance.""")
@cli_util.option('--lifecycle-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), help=u"""Filter resources whose lifecycleState matches the specified value.""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--page', help=u"""Page representing the requested page of items.""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeCreated", "displayName"]), help=u"""The field to sort by. Only one sort order may be provided. Default order for timeCreated is descending. Default order for displayName is ascending.""")
@cli_util.option('--id', help=u"""Filter resources by [OCID]. Must be a valid OCID of the resource type.""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'DigitalTwinRelationshipCollection'})
@cli_util.wrap_exceptions
def list_digital_twin_relationships(ctx, from_json, all_pages, page_size, iot_domain_id, display_name, content_path, source_digital_twin_instance_id, target_digital_twin_instance_id, lifecycle_state, limit, page, sort_order, sort_by, id):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    kwargs = {}
    if display_name is not None:
        kwargs['display_name'] = display_name
    if content_path is not None:
        kwargs['content_path'] = content_path
    if source_digital_twin_instance_id is not None:
        kwargs['source_digital_twin_instance_id'] = source_digital_twin_instance_id
    if target_digital_twin_instance_id is not None:
        kwargs['target_digital_twin_instance_id'] = target_digital_twin_instance_id
    if lifecycle_state is not None:
        kwargs['lifecycle_state'] = lifecycle_state
    if limit is not None:
        kwargs['limit'] = limit
    if page is not None:
        kwargs['page'] = page
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    if id is not None:
        kwargs['id'] = id
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_digital_twin_relationships,
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_digital_twin_relationships,
            limit,
            page_size,
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    else:
        result = client.list_digital_twin_relationships(
            iot_domain_id=iot_domain_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@iot_domain_group_group.command(name=cli_util.override('iot.list_iot_domain_groups.command_name', 'list'), help=u"""Retrieves a list of IoT domain groups within the specified compartment. \n[Command Reference](listIotDomainGroups)""")
@cli_util.option('--compartment-id', required=True, help=u"""The [OCID] of the compartment in which to list resources.""")
@cli_util.option('--id', help=u"""Filter resources by [OCID]. Must be a valid OCID of the resource type.""")
@cli_util.option('--display-name', help=u"""Filter resources whose display name matches the specified value.""")
@cli_util.option('--lifecycle-state', type=custom_types.CliCaseInsensitiveChoice(["CREATING", "UPDATING", "ACTIVE", "DELETING", "DELETED", "FAILED"]), help=u"""Filter resources whose lifecycleState matches the specified value.""")
@cli_util.option('--type', type=custom_types.CliCaseInsensitiveChoice(["PRODUCTION", "DEVELOPMENT", "STANDARD", "LIGHTWEIGHT"]), help=u"""Filter resources by type. Valid values are LIGHTWEIGHT or STANDARD.""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--page', help=u"""For list pagination: The value of the opc-next-page response header from the previous \"List\" call. For important details on how pagination works, see [List Pagination].""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeCreated", "displayName"]), help=u"""The field to sort by. Only one sort order may be provided. Default order for timeCreated is descending. Default order for displayName is ascending.""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'IotDomainGroupCollection'})
@cli_util.wrap_exceptions
def list_iot_domain_groups(ctx, from_json, all_pages, page_size, compartment_id, id, display_name, lifecycle_state, type, limit, page, sort_order, sort_by):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    kwargs = {}
    if id is not None:
        kwargs['id'] = id
    if display_name is not None:
        kwargs['display_name'] = display_name
    if lifecycle_state is not None:
        kwargs['lifecycle_state'] = lifecycle_state
    if type is not None:
        kwargs['type'] = type
    if limit is not None:
        kwargs['limit'] = limit
    if page is not None:
        kwargs['page'] = page
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_iot_domain_groups,
            compartment_id=compartment_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_iot_domain_groups,
            limit,
            page_size,
            compartment_id=compartment_id,
            **kwargs
        )
    else:
        result = client.list_iot_domain_groups(
            compartment_id=compartment_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.list_iot_domains.command_name', 'list'), help=u"""Retrieves a list of IoT domains within the specified compartment. \n[Command Reference](listIotDomains)""")
@cli_util.option('--compartment-id', required=True, help=u"""The [OCID] of the compartment in which to list resources.""")
@cli_util.option('--id', help=u"""Filter resources by [OCID]. Must be a valid OCID of the resource type.""")
@cli_util.option('--iot-domain-group-id', help=u"""Filter resources that match the specified [OCID] of the IoT domain group.""")
@cli_util.option('--display-name', help=u"""Filter resources whose display name matches the specified value.""")
@cli_util.option('--lifecycle-state', type=custom_types.CliCaseInsensitiveChoice(["CREATING", "UPDATING", "ACTIVE", "DELETING", "DELETED", "FAILED"]), help=u"""Filter resources whose lifecycleState matches the specified value.""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--page', help=u"""For list pagination: The value of the opc-next-page response header from the previous \"List\" call. For important details on how pagination works, see [List Pagination].""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeCreated", "displayName"]), help=u"""The field to sort by. Only one sort order may be provided. Default order for timeCreated is descending. Default order for displayName is ascending.""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'IotDomainCollection'})
@cli_util.wrap_exceptions
def list_iot_domains(ctx, from_json, all_pages, page_size, compartment_id, id, iot_domain_group_id, display_name, lifecycle_state, limit, page, sort_order, sort_by):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    kwargs = {}
    if id is not None:
        kwargs['id'] = id
    if iot_domain_group_id is not None:
        kwargs['iot_domain_group_id'] = iot_domain_group_id
    if display_name is not None:
        kwargs['display_name'] = display_name
    if lifecycle_state is not None:
        kwargs['lifecycle_state'] = lifecycle_state
    if limit is not None:
        kwargs['limit'] = limit
    if page is not None:
        kwargs['page'] = page
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_iot_domains,
            compartment_id=compartment_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_iot_domains,
            limit,
            page_size,
            compartment_id=compartment_id,
            **kwargs
        )
    else:
        result = client.list_iot_domains(
            compartment_id=compartment_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@work_request_group.command(name=cli_util.override('iot.list_work_request_errors.command_name', 'list-work-request-errors'), help=u"""Lists errors associated with the specified work request. \n[Command Reference](listWorkRequestErrors)""")
@cli_util.option('--work-request-id', required=True, help=u"""The [OCID] of the asynchronous work request.""")
@cli_util.option('--page', help=u"""For list pagination: The value of the opc-next-page response header from the previous \"List\" call. For important details on how pagination works, see [List Pagination].""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeCreated"]), help=u"""The field to sort by. Only one sort order can be specified. The default order for `timeCreated` is descending.""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'WorkRequestErrorCollection'})
@cli_util.wrap_exceptions
def list_work_request_errors(ctx, from_json, all_pages, page_size, work_request_id, page, limit, sort_by, sort_order):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    if isinstance(work_request_id, six.string_types) and len(work_request_id.strip()) == 0:
        raise click.UsageError('Parameter --work-request-id cannot be whitespace or empty string')

    kwargs = {}
    if page is not None:
        kwargs['page'] = page
    if limit is not None:
        kwargs['limit'] = limit
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_work_request_errors,
            work_request_id=work_request_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_work_request_errors,
            limit,
            page_size,
            work_request_id=work_request_id,
            **kwargs
        )
    else:
        result = client.list_work_request_errors(
            work_request_id=work_request_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@work_request_group.command(name=cli_util.override('iot.list_work_request_logs.command_name', 'list-work-request-logs'), help=u"""Lists the logs associated with the specified work request. \n[Command Reference](listWorkRequestLogs)""")
@cli_util.option('--work-request-id', required=True, help=u"""The [OCID] of the asynchronous work request.""")
@cli_util.option('--page', help=u"""For list pagination: The value of the opc-next-page response header from the previous \"List\" call. For important details on how pagination works, see [List Pagination].""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeCreated"]), help=u"""The field to sort by. Only one sort order can be specified. The default order for `timeCreated` is descending.""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'WorkRequestLogEntryCollection'})
@cli_util.wrap_exceptions
def list_work_request_logs(ctx, from_json, all_pages, page_size, work_request_id, page, limit, sort_by, sort_order):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    if isinstance(work_request_id, six.string_types) and len(work_request_id.strip()) == 0:
        raise click.UsageError('Parameter --work-request-id cannot be whitespace or empty string')

    kwargs = {}
    if page is not None:
        kwargs['page'] = page
    if limit is not None:
        kwargs['limit'] = limit
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_work_request_logs,
            work_request_id=work_request_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_work_request_logs,
            limit,
            page_size,
            work_request_id=work_request_id,
            **kwargs
        )
    else:
        result = client.list_work_request_logs(
            work_request_id=work_request_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@work_request_group.command(name=cli_util.override('iot.list_work_requests.command_name', 'list'), help=u"""Lists work requests in the specified compartment. \n[Command Reference](listWorkRequests)""")
@cli_util.option('--compartment-id', required=True, help=u"""The [OCID] of the compartment in which to list resources.""")
@cli_util.option('--id', help=u"""The [OCID] of the asynchronous work request.""")
@cli_util.option('--status', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), help=u"""A filter to return only the resources that match the given lifecycle state.""")
@cli_util.option('--resource-id', help=u"""The [OCID] of the resource affected by the work request.""")
@cli_util.option('--page', help=u"""For list pagination: The value of the opc-next-page response header from the previous \"List\" call. For important details on how pagination works, see [List Pagination].""")
@cli_util.option('--limit', type=click.INT, help=u"""For list pagination. The maximum number of results per page, or items to return in a paginated \"List\" call. For important details about how pagination works, see [List Pagination].""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""Specifies sort order to use, either ASC (ascending) or DESC (descending).""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeAccepted"]), help=u"""The field to sort by. Only one sort order can be specified. Default order for `timeAccepted` is descending.""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'iot', 'class': 'WorkRequestSummaryCollection'})
@cli_util.wrap_exceptions
def list_work_requests(ctx, from_json, all_pages, page_size, compartment_id, id, status, resource_id, page, limit, sort_order, sort_by):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    kwargs = {}
    if id is not None:
        kwargs['id'] = id
    if status is not None:
        kwargs['status'] = status
    if resource_id is not None:
        kwargs['resource_id'] = resource_id
    if page is not None:
        kwargs['page'] = page
    if limit is not None:
        kwargs['limit'] = limit
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('iot', 'iot', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_work_requests,
            compartment_id=compartment_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_work_requests,
            limit,
            page_size,
            compartment_id=compartment_id,
            **kwargs
        )
    else:
        result = client.list_work_requests(
            compartment_id=compartment_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)


@digital_twin_adapter_group.command(name=cli_util.override('iot.update_digital_twin_adapter.command_name', 'update'), help=u"""Updates the details of digital twin adapter identified by the specified OCID. \n[Command Reference](updateDigitalTwinAdapter)""")
@cli_util.option('--digital-twin-adapter-id', required=True, help=u"""The [OCID] of the digital twin adapter.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--inbound-envelope', type=custom_types.CLI_COMPLEX_TYPE, help=u"""""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--inbound-routes', type=custom_types.CLI_COMPLEX_TYPE, help=u"""list of routes

This option is a JSON list with items of type DigitalTwinAdapterInboundRoute.  For documentation on DigitalTwinAdapterInboundRoute please see our API reference: https://docs.oracle.com/en-us/iaas/api/#/en/iot/20250531/datatypes/DigitalTwinAdapterInboundRoute.""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--force', help="""Perform update without prompting for confirmation.""", is_flag=True)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'inbound-envelope': {'module': 'iot', 'class': 'DigitalTwinAdapterInboundEnvelope'}, 'inbound-routes': {'module': 'iot', 'class': 'list[DigitalTwinAdapterInboundRoute]'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'inbound-envelope': {'module': 'iot', 'class': 'DigitalTwinAdapterInboundEnvelope'}, 'inbound-routes': {'module': 'iot', 'class': 'list[DigitalTwinAdapterInboundRoute]'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'DigitalTwinAdapter'})
@cli_util.wrap_exceptions
def update_digital_twin_adapter(ctx, from_json, force, wait_for_state, max_wait_seconds, wait_interval_seconds, digital_twin_adapter_id, display_name, description, inbound_envelope, inbound_routes, freeform_tags, defined_tags, if_match):

    if isinstance(digital_twin_adapter_id, six.string_types) and len(digital_twin_adapter_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-adapter-id cannot be whitespace or empty string')
    if not force:
        if inbound_envelope or inbound_routes or freeform_tags or defined_tags:
            if not click.confirm("WARNING: Updates to inbound-envelope and inbound-routes and freeform-tags and defined-tags will replace any existing values. Are you sure you want to continue?"):
                ctx.abort()

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if inbound_envelope is not None:
        _details['inboundEnvelope'] = cli_util.parse_json_parameter("inbound_envelope", inbound_envelope)

    if inbound_routes is not None:
        _details['inboundRoutes'] = cli_util.parse_json_parameter("inbound_routes", inbound_routes)

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.update_digital_twin_adapter(
        digital_twin_adapter_id=digital_twin_adapter_id,
        update_digital_twin_adapter_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_adapter') and callable(getattr(client, 'get_digital_twin_adapter')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_digital_twin_adapter(result.data.id), 'lifecycle_state', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_instance_group.command(name=cli_util.override('iot.update_digital_twin_instance.command_name', 'update'), help=u"""Updates the details of digital twin instance identified by the specified OCID. \n[Command Reference](updateDigitalTwinInstance)""")
@cli_util.option('--digital-twin-instance-id', required=True, help=u"""The [OCID] of digital twin instance.""")
@cli_util.option('--auth-id', help=u"""The [OCID] of the resource (like VaultSecret, ClientCertificate etc.,) used to authenticate the digital twin instance.""")
@cli_util.option('--external-key', help=u"""A unique identifier for the physical entity (typically an IoT device) represented by the digital twin instance. This could be a Bluetooth address, Ethernet MAC address, or serial number, depending on the use case. If not provided, the system will automatically generate one.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--digital-twin-adapter-id', help=u"""The [OCID] of the digital twin adapter.""")
@cli_util.option('--digital-twin-model-id', help=u"""The [OCID] of the digital twin model.""")
@cli_util.option('--digital-twin-model-spec-uri', help=u"""The URI of the digital twin model specification.""")
@cli_util.option('--gateways', type=custom_types.CLI_COMPLEX_TYPE, help=u"""An array of unique ids ([OCIDs]) of the IoT digital twin instances with connectivityType equals to GATEWAY.""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--force', help="""Perform update without prompting for confirmation.""", is_flag=True)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'gateways': {'module': 'iot', 'class': 'list[string]'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'gateways': {'module': 'iot', 'class': 'list[string]'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'DigitalTwinInstance'})
@cli_util.wrap_exceptions
def update_digital_twin_instance(ctx, from_json, force, wait_for_state, max_wait_seconds, wait_interval_seconds, digital_twin_instance_id, auth_id, external_key, display_name, description, digital_twin_adapter_id, digital_twin_model_id, digital_twin_model_spec_uri, gateways, freeform_tags, defined_tags, if_match):

    if isinstance(digital_twin_instance_id, six.string_types) and len(digital_twin_instance_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-instance-id cannot be whitespace or empty string')
    if not force:
        if gateways or freeform_tags or defined_tags:
            if not click.confirm("WARNING: Updates to gateways and freeform-tags and defined-tags will replace any existing values. Are you sure you want to continue?"):
                ctx.abort()

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}

    if auth_id is not None:
        _details['authId'] = auth_id

    if external_key is not None:
        _details['externalKey'] = external_key

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if digital_twin_adapter_id is not None:
        _details['digitalTwinAdapterId'] = digital_twin_adapter_id

    if digital_twin_model_id is not None:
        _details['digitalTwinModelId'] = digital_twin_model_id

    if digital_twin_model_spec_uri is not None:
        _details['digitalTwinModelSpecUri'] = digital_twin_model_spec_uri

    if gateways is not None:
        _details['gateways'] = cli_util.parse_json_parameter("gateways", gateways)

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.update_digital_twin_instance(
        digital_twin_instance_id=digital_twin_instance_id,
        update_digital_twin_instance_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_instance') and callable(getattr(client, 'get_digital_twin_instance')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_digital_twin_instance(result.data.id), 'lifecycle_state', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_model_group.command(name=cli_util.override('iot.update_digital_twin_model.command_name', 'update'), help=u"""Updates the details of the digital twin model identified by the specified OCID. \n[Command Reference](updateDigitalTwinModel)""")
@cli_util.option('--digital-twin-model-id', required=True, help=u"""The [OCID] of digital twin model.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. If left blank, the display name will be derived from the spec.""")
@cli_util.option('--description', help=u"""A short description of the resource. If left blank, the description will be derived from the spec.""")
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--force', help="""Perform update without prompting for confirmation.""", is_flag=True)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'DigitalTwinModel'})
@cli_util.wrap_exceptions
def update_digital_twin_model(ctx, from_json, force, wait_for_state, max_wait_seconds, wait_interval_seconds, digital_twin_model_id, display_name, description, freeform_tags, defined_tags, if_match):

    if isinstance(digital_twin_model_id, six.string_types) and len(digital_twin_model_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-model-id cannot be whitespace or empty string')
    if not force:
        if freeform_tags or defined_tags:
            if not click.confirm("WARNING: Updates to freeform-tags and defined-tags will replace any existing values. Are you sure you want to continue?"):
                ctx.abort()

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.update_digital_twin_model(
        digital_twin_model_id=digital_twin_model_id,
        update_digital_twin_model_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_model') and callable(getattr(client, 'get_digital_twin_model')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_digital_twin_model(result.data.id), 'lifecycle_state', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@digital_twin_relationship_group.command(name=cli_util.override('iot.update_digital_twin_relationship.command_name', 'update'), help=u"""Updates the details of digital twin relationship identified by the specified OCID. \n[Command Reference](updateDigitalTwinRelationship)""")
@cli_util.option('--digital-twin-relationship-id', required=True, help=u"""The [OCID] of digital twin relationship.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--content', type=custom_types.CLI_COMPLEX_TYPE, help=u"""The value(s) of the relationship properties defined in the source digital twin model.""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--force', help="""Perform update without prompting for confirmation.""", is_flag=True)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "DELETED"]), multiple=True, help="""This operation creates, modifies or deletes a resource that has a defined lifecycle state. Specify this option to perform the action and then wait until the resource reaches a given lifecycle state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACTIVE --wait-for-state DELETED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the resource to reach the lifecycle state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the resource has reached the lifecycle state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'content': {'module': 'iot', 'class': 'dict(str, object)'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'content': {'module': 'iot', 'class': 'dict(str, object)'}, 'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}}, output_type={'module': 'iot', 'class': 'DigitalTwinRelationship'})
@cli_util.wrap_exceptions
def update_digital_twin_relationship(ctx, from_json, force, wait_for_state, max_wait_seconds, wait_interval_seconds, digital_twin_relationship_id, display_name, description, content, freeform_tags, defined_tags, if_match):

    if isinstance(digital_twin_relationship_id, six.string_types) and len(digital_twin_relationship_id.strip()) == 0:
        raise click.UsageError('Parameter --digital-twin-relationship-id cannot be whitespace or empty string')
    if not force:
        if content or freeform_tags or defined_tags:
            if not click.confirm("WARNING: Updates to content and freeform-tags and defined-tags will replace any existing values. Are you sure you want to continue?"):
                ctx.abort()

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if content is not None:
        _details['content'] = cli_util.parse_json_parameter("content", content)

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.update_digital_twin_relationship(
        digital_twin_relationship_id=digital_twin_relationship_id,
        update_digital_twin_relationship_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_digital_twin_relationship') and callable(getattr(client, 'get_digital_twin_relationship')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds

                click.echo('Action completed. Waiting until the resource has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_digital_twin_relationship(result.data.id), 'lifecycle_state', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the resource entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for resource to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the resource to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group.command(name=cli_util.override('iot.update_iot_domain.command_name', 'update'), help=u"""Updates the details of IoT domain identified by the specified OCID. \n[Command Reference](updateIotDomain)""")
@cli_util.option('--iot-domain-id', required=True, help=u"""The [OCID] of the IoT domain.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--force', help="""Perform update without prompting for confirmation.""", is_flag=True)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.wrap_exceptions
def update_iot_domain(ctx, from_json, force, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_id, display_name, description, freeform_tags, defined_tags, if_match):

    if isinstance(iot_domain_id, six.string_types) and len(iot_domain_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-id cannot be whitespace or empty string')
    if not force:
        if freeform_tags or defined_tags:
            if not click.confirm("WARNING: Updates to freeform-tags and defined-tags will replace any existing values. Are you sure you want to continue?"):
                ctx.abort()

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.update_iot_domain(
        iot_domain_id=iot_domain_id,
        update_iot_domain_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)


@iot_domain_group_group.command(name=cli_util.override('iot.update_iot_domain_group.command_name', 'update'), help=u"""Updates the details of IoT domain group identified by the specified OCID. \n[Command Reference](updateIotDomainGroup)""")
@cli_util.option('--iot-domain-group-id', required=True, help=u"""The [OCID] of an IoT Domain Group.""")
@cli_util.option('--display-name', help=u"""A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.""")
@cli_util.option('--description', help=u"""A short description of the resource.""")
@cli_util.option('--freeform-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags].

Example: `{\"Department\": \"Finance\"}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--defined-tags', type=custom_types.CLI_COMPLEX_TYPE, help=u"""Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags].

Example: `{\"Operations\": {\"CostCenter\": \"42\"}}`""" + custom_types.cli_complex_type.COMPLEX_TYPE_HELP)
@cli_util.option('--if-match', help=u"""For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` parameter to the value of the etag from a previous GET or POST response for that resource. The resource will be updated or deleted only if the etag you provide matches the resource's current etag value.""")
@cli_util.option('--force', help="""Perform update without prompting for confirmation.""", is_flag=True)
@cli_util.option('--wait-for-state', type=custom_types.CliCaseInsensitiveChoice(["ACCEPTED", "IN_PROGRESS", "WAITING", "NEEDS_ATTENTION", "FAILED", "SUCCEEDED"]), multiple=True, help="""This operation asynchronously creates, modifies or deletes a resource and uses a work request to track the progress of the operation. Specify this option to perform the action and then wait until the work request reaches a certain state. Multiple states can be specified, returning on the first state. For example, --wait-for-state ACCEPTED --wait-for-state SUCCEEDED would return on whichever lifecycle state is reached first. If timeout is reached, a return code of 2 is returned. For any other error, a return code of 1 is returned.""")
@cli_util.option('--max-wait-seconds', type=click.INT, help="""The maximum time to wait for the work request to reach the state defined by --wait-for-state. Defaults to 1200 seconds.""")
@cli_util.option('--wait-interval-seconds', type=click.INT, help="""Check every --wait-interval-seconds to see whether the work request has reached the state defined by --wait-for-state. Defaults to 30 seconds.""")
@json_skeleton_utils.get_cli_json_input_option({'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'freeform-tags': {'module': 'iot', 'class': 'dict(str, string)'}, 'defined-tags': {'module': 'iot', 'class': 'dict(str, dict(str, object))'}})
@cli_util.wrap_exceptions
def update_iot_domain_group(ctx, from_json, force, wait_for_state, max_wait_seconds, wait_interval_seconds, iot_domain_group_id, display_name, description, freeform_tags, defined_tags, if_match):

    if isinstance(iot_domain_group_id, six.string_types) and len(iot_domain_group_id.strip()) == 0:
        raise click.UsageError('Parameter --iot-domain-group-id cannot be whitespace or empty string')
    if not force:
        if freeform_tags or defined_tags:
            if not click.confirm("WARNING: Updates to freeform-tags and defined-tags will replace any existing values. Are you sure you want to continue?"):
                ctx.abort()

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}

    if display_name is not None:
        _details['displayName'] = display_name

    if description is not None:
        _details['description'] = description

    if freeform_tags is not None:
        _details['freeformTags'] = cli_util.parse_json_parameter("freeform_tags", freeform_tags)

    if defined_tags is not None:
        _details['definedTags'] = cli_util.parse_json_parameter("defined_tags", defined_tags)

    client = cli_util.build_client('iot', 'iot', ctx)
    result = client.update_iot_domain_group(
        iot_domain_group_id=iot_domain_group_id,
        update_iot_domain_group_details=_details,
        **kwargs
    )
    if wait_for_state:

        if hasattr(client, 'get_work_request') and callable(getattr(client, 'get_work_request')):
            try:
                wait_period_kwargs = {}
                if max_wait_seconds is not None:
                    wait_period_kwargs['max_wait_seconds'] = max_wait_seconds
                if wait_interval_seconds is not None:
                    wait_period_kwargs['max_interval_seconds'] = wait_interval_seconds
                if 'opc-work-request-id' not in result.headers:
                    click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state')
                    cli_util.render_response(result, ctx)
                    return

                click.echo('Action completed. Waiting until the work request has entered state: {}'.format(wait_for_state), file=sys.stderr)
                result = oci.wait_until(client, client.get_work_request(result.headers['opc-work-request-id']), 'status', wait_for_state, **wait_period_kwargs)
            except oci.exceptions.MaximumWaitTimeExceeded as e:
                # If we fail, we should show an error, but we should still provide the information to the customer
                click.echo('Failed to wait until the work request entered the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                sys.exit(2)
            except Exception:
                click.echo('Encountered error while waiting for work request to enter the specified state. Outputting last known resource state', file=sys.stderr)
                cli_util.render_response(result, ctx)
                raise
        else:
            click.echo('Unable to wait for the work request to enter the specified state', file=sys.stderr)
    cli_util.render_response(result, ctx)
