# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
#
# Code generated by aaz-dev-tools
# --------------------------------------------------------------------------------------------

# pylint: skip-file
# flake8: noqa

from azure.cli.core.aaz import *


@register_command(
    "search service create",
)
class Create(AAZCommand):
    """Create a search service in the given resource group. If the search service already exists, all properties will be updated with the given values.
    """

    _aaz_info = {
        "version": "2023-11-01",
        "resources": [
            ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.search/searchservices/{}", "2023-11-01"],
        ]
    }

    AZ_SUPPORT_NO_WAIT = True

    def _handler(self, command_args):
        super()._handler(command_args)
        return self.build_lro_poller(self._execute_operations, self._output)

    _args_schema = None

    @classmethod
    def _build_arguments_schema(cls, *args, **kwargs):
        if cls._args_schema is not None:
            return cls._args_schema
        cls._args_schema = super()._build_arguments_schema(*args, **kwargs)

        # define Arg Group ""

        _args_schema = cls._args_schema
        _args_schema.resource_group = AAZResourceGroupNameArg(
            required=True,
        )
        _args_schema.search_service_name = AAZStrArg(
            options=["-n", "--name", "--search-service-name"],
            help="The name of the Azure Cognitive Search service to create or update. Search service names must only contain lowercase letters, digits or dashes, cannot use dash as the first two or last one characters, cannot contain consecutive dashes, and must be between 2 and 60 characters in length. Search service names must be globally unique since they are part of the service URI (`https://<name>.search.windows.net`). You cannot change the service name after the service is created.",
            required=True,
        )

        # define Arg Group "AuthOptions"

        _args_schema = cls._args_schema
        _args_schema.aad_auth_failure_mode = AAZStrArg(
            options=["--aad-auth-failure-mode"],
            arg_group="AuthOptions",
            help="Describes what response the data plane API of a Search service would send for requests that failed authentication.",
            enum={"http401WithBearerChallenge": "http401WithBearerChallenge", "http403": "http403"},
        )
        _args_schema.api_key_only = AAZObjectArg(
            options=["--api-key-only"],
            arg_group="AuthOptions",
            help="Indicates that only the API key needs to be used for authentication.",
            blank={},
        )

        # define Arg Group "Identity"

        _args_schema = cls._args_schema
        _args_schema.identity_type = AAZStrArg(
            options=["--identity-type"],
            arg_group="Identity",
            help="The identity type.",
            enum={"None": "None", "SystemAssigned": "SystemAssigned"},
        )

        # define Arg Group "NetworkRuleSet"

        _args_schema = cls._args_schema
        _args_schema.ip_rules_internal = AAZListArg(
            options=["--ip-rules-internal"],
            arg_group="NetworkRuleSet",
            help="A list of IP restriction rules that defines the inbound network(s) with allowing access to the search service endpoint. At the meantime, all other public IP networks are blocked by the firewall. These restriction rules are applied only when the 'publicNetworkAccess' of the search service is 'enabled'; otherwise, traffic over public interface is not allowed even with any public IP rules, and private endpoint connections would be the exclusive access method.",
        )

        ip_rules_internal = cls._args_schema.ip_rules_internal
        ip_rules_internal.Element = AAZObjectArg()

        _element = cls._args_schema.ip_rules_internal.Element
        _element.value = AAZStrArg(
            options=["value"],
            help="Value corresponding to a single IPv4 address (eg., 123.1.2.3) or an IP range in CIDR format (eg., 123.1.2.3/24) to be allowed.",
        )

        # define Arg Group "Properties"

        _args_schema = cls._args_schema
        _args_schema.disable_local_auth = AAZBoolArg(
            options=["--disable-local-auth"],
            arg_group="Properties",
            help="When set to true, calls to the search service will not be permitted to utilize API keys for authentication. This cannot be set to true if 'dataPlaneAuthOptions' are defined.",
            nullable=True,
        )
        _args_schema.hosting_mode = AAZStrArg(
            options=["--hosting-mode"],
            arg_group="Properties",
            help="Applicable only for the standard3 SKU. You can set this property to enable up to 3 high density partitions that allow up to 1000 indexes, which is much higher than the maximum indexes allowed for any other SKU. For the standard3 SKU, the value is either 'default' or 'highDensity'. For all other SKUs, this value must be 'default'.",
            default="default",
            enum={"default": "default", "highDensity": "highDensity"},
        )
        _args_schema.partition_count = AAZIntArg(
            options=["--partition-count"],
            arg_group="Properties",
            help="The number of partitions in the search service; if specified, it can be 1, 2, 3, 4, 6, or 12. Values greater than 1 are only valid for standard SKUs. For 'standard3' services with hostingMode set to 'highDensity', the allowed values are between 1 and 3.",
            default=1,
            fmt=AAZIntArgFormat(
                maximum=12,
                minimum=1,
            ),
        )
        _args_schema.public_network_access = AAZStrArg(
            options=["--public-access", "--public-network-access"],
            arg_group="Properties",
            help="This value can be set to 'enabled' to avoid breaking changes on existing customer resources and templates. If set to 'disabled', traffic over public interface is not allowed, and private endpoint connections would be the exclusive access method.",
            default="enabled",
            enum={"disabled": "disabled", "enabled": "enabled"},
        )
        _args_schema.replica_count = AAZIntArg(
            options=["--replica-count"],
            arg_group="Properties",
            help="The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU.",
            default=1,
            fmt=AAZIntArgFormat(
                maximum=12,
                minimum=1,
            ),
        )
        _args_schema.semantic_search = AAZStrArg(
            options=["--semantic-search"],
            arg_group="Properties",
            help="Sets options that control the availability of semantic search. This configuration is only possible for certain Azure Cognitive Search SKUs in certain locations.",
            nullable=True,
            enum={"disabled": "disabled", "free": "free", "standard": "standard"},
        )

        # define Arg Group "Service"

        _args_schema = cls._args_schema
        _args_schema.location = AAZResourceLocationArg(
            arg_group="Service",
            help="The geo-location where the resource lives",
            required=True,
            fmt=AAZResourceLocationArgFormat(
                resource_group_arg="resource_group",
            ),
        )
        _args_schema.tags = AAZDictArg(
            options=["--tags"],
            arg_group="Service",
            help="Resource tags.",
        )

        tags = cls._args_schema.tags
        tags.Element = AAZStrArg()

        # define Arg Group "Sku"

        _args_schema = cls._args_schema
        _args_schema.sku = AAZStrArg(
            options=["--sku"],
            arg_group="Sku",
            help="The SKU of the search service. Valid values include: 'free': Shared service. 'basic': Dedicated service with up to 3 replicas. 'standard': Dedicated service with up to 12 partitions and 12 replicas. 'standard2': Similar to standard, but with more capacity per search unit. 'standard3': The largest Standard offering with up to 12 partitions and 12 replicas (or up to 3 partitions with more indexes if you also set the hostingMode property to 'highDensity'). 'storage_optimized_l1': Supports 1TB per partition, up to 12 partitions. 'storage_optimized_l2': Supports 2TB per partition, up to 12 partitions.'",
            required=True,
            enum={"basic": "basic", "free": "free", "standard": "standard", "standard2": "standard2", "standard3": "standard3", "storage_optimized_l1": "storage_optimized_l1", "storage_optimized_l2": "storage_optimized_l2"},
        )
        return cls._args_schema

    def _execute_operations(self):
        self.pre_operations()
        yield self.ServicesCreateOrUpdate(ctx=self.ctx)()
        self.post_operations()

    @register_callback
    def pre_operations(self):
        pass

    @register_callback
    def post_operations(self):
        pass

    def _output(self, *args, **kwargs):
        result = self.deserialize_output(self.ctx.vars.instance, client_flatten=True)
        return result

    class ServicesCreateOrUpdate(AAZHttpOperation):
        CLIENT_TYPE = "MgmtClient"

        def __call__(self, *args, **kwargs):
            request = self.make_request()
            session = self.client.send_request(request=request, stream=False, **kwargs)
            if session.http_response.status_code in [202]:
                return self.client.build_lro_polling(
                    self.ctx.args.no_wait,
                    session,
                    self.on_200_201,
                    self.on_error,
                    lro_options={"final-state-via": "azure-async-operation"},
                    path_format_arguments=self.url_parameters,
                )
            if session.http_response.status_code in [200, 201]:
                return self.client.build_lro_polling(
                    self.ctx.args.no_wait,
                    session,
                    self.on_200_201,
                    self.on_error,
                    lro_options={"final-state-via": "azure-async-operation"},
                    path_format_arguments=self.url_parameters,
                )

            return self.on_error(session.http_response)

        @property
        def url(self):
            return self.client.format_url(
                "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Search/searchServices/{searchServiceName}",
                **self.url_parameters
            )

        @property
        def method(self):
            return "PUT"

        @property
        def error_format(self):
            return "ODataV4Format"

        @property
        def url_parameters(self):
            parameters = {
                **self.serialize_url_param(
                    "resourceGroupName", self.ctx.args.resource_group,
                    required=True,
                ),
                **self.serialize_url_param(
                    "searchServiceName", self.ctx.args.search_service_name,
                    required=True,
                ),
                **self.serialize_url_param(
                    "subscriptionId", self.ctx.subscription_id,
                    required=True,
                ),
            }
            return parameters

        @property
        def query_parameters(self):
            parameters = {
                **self.serialize_query_param(
                    "api-version", "2023-11-01",
                    required=True,
                ),
            }
            return parameters

        @property
        def header_parameters(self):
            parameters = {
                **self.serialize_header_param(
                    "Content-Type", "application/json",
                ),
                **self.serialize_header_param(
                    "Accept", "application/json",
                ),
            }
            return parameters

        @property
        def content(self):
            _content_value, _builder = self.new_content_builder(
                self.ctx.args,
                typ=AAZObjectType,
                typ_kwargs={"flags": {"required": True, "client_flatten": True}}
            )
            _builder.set_prop("identity", AAZObjectType)
            _builder.set_prop("location", AAZStrType, ".location", typ_kwargs={"flags": {"required": True}})
            _builder.set_prop("properties", AAZObjectType, typ_kwargs={"flags": {"client_flatten": True}})
            _builder.set_prop("sku", AAZObjectType, ".", typ_kwargs={"flags": {"required": True}})
            _builder.set_prop("tags", AAZDictType, ".tags")

            identity = _builder.get(".identity")
            if identity is not None:
                identity.set_prop("type", AAZStrType, ".identity_type", typ_kwargs={"flags": {"required": True}})

            properties = _builder.get(".properties")
            if properties is not None:
                properties.set_prop("authOptions", AAZObjectType)
                properties.set_prop("disableLocalAuth", AAZBoolType, ".disable_local_auth", typ_kwargs={"nullable": True})
                properties.set_prop("hostingMode", AAZStrType, ".hosting_mode")
                properties.set_prop("networkRuleSet", AAZObjectType)
                properties.set_prop("partitionCount", AAZIntType, ".partition_count")
                properties.set_prop("publicNetworkAccess", AAZStrType, ".public_network_access")
                properties.set_prop("replicaCount", AAZIntType, ".replica_count")
                properties.set_prop("semanticSearch", AAZStrType, ".semantic_search", typ_kwargs={"nullable": True})

            auth_options = _builder.get(".properties.authOptions")
            if auth_options is not None:
                auth_options.set_prop("aadOrApiKey", AAZObjectType)
                auth_options.set_prop("apiKeyOnly", AAZObjectType, ".api_key_only")

            aad_or_api_key = _builder.get(".properties.authOptions.aadOrApiKey")
            if aad_or_api_key is not None:
                aad_or_api_key.set_prop("aadAuthFailureMode", AAZStrType, ".aad_auth_failure_mode")

            network_rule_set = _builder.get(".properties.networkRuleSet")
            if network_rule_set is not None:
                network_rule_set.set_prop("ipRules", AAZListType, ".ip_rules_internal")

            ip_rules = _builder.get(".properties.networkRuleSet.ipRules")
            if ip_rules is not None:
                ip_rules.set_elements(AAZObjectType, ".")

            _elements = _builder.get(".properties.networkRuleSet.ipRules[]")
            if _elements is not None:
                _elements.set_prop("value", AAZStrType, ".value")

            sku = _builder.get(".sku")
            if sku is not None:
                sku.set_prop("name", AAZStrType, ".sku", typ_kwargs={"flags": {"required": True}})

            tags = _builder.get(".tags")
            if tags is not None:
                tags.set_elements(AAZStrType, ".")

            return self.serialize_content(_content_value)

        def on_200_201(self, session):
            data = self.deserialize_http_content(session)
            self.ctx.set_var(
                "instance",
                data,
                schema_builder=self._build_schema_on_200_201
            )

        _schema_on_200_201 = None

        @classmethod
        def _build_schema_on_200_201(cls):
            if cls._schema_on_200_201 is not None:
                return cls._schema_on_200_201

            cls._schema_on_200_201 = AAZObjectType()

            _schema_on_200_201 = cls._schema_on_200_201
            _schema_on_200_201.id = AAZStrType(
                flags={"read_only": True},
            )
            _schema_on_200_201.identity = AAZObjectType()
            _schema_on_200_201.location = AAZStrType(
                flags={"required": True},
            )
            _schema_on_200_201.name = AAZStrType(
                flags={"read_only": True},
            )
            _schema_on_200_201.properties = AAZObjectType(
                flags={"client_flatten": True},
            )
            _schema_on_200_201.sku = AAZObjectType(
                flags={"required": True},
            )
            _schema_on_200_201.tags = AAZDictType()
            _schema_on_200_201.type = AAZStrType(
                flags={"read_only": True},
            )

            identity = cls._schema_on_200_201.identity
            identity.principal_id = AAZStrType(
                serialized_name="principalId",
                flags={"read_only": True},
            )
            identity.tenant_id = AAZStrType(
                serialized_name="tenantId",
                flags={"read_only": True},
            )
            identity.type = AAZStrType(
                flags={"required": True},
            )

            properties = cls._schema_on_200_201.properties
            properties.auth_options = AAZObjectType(
                serialized_name="authOptions",
            )
            properties.disable_local_auth = AAZBoolType(
                serialized_name="disableLocalAuth",
                nullable=True,
            )
            properties.encryption_with_cmk = AAZObjectType(
                serialized_name="encryptionWithCmk",
            )
            properties.hosting_mode = AAZStrType(
                serialized_name="hostingMode",
            )
            properties.network_rule_set = AAZObjectType(
                serialized_name="networkRuleSet",
            )
            properties.partition_count = AAZIntType(
                serialized_name="partitionCount",
            )
            properties.private_endpoint_connections = AAZListType(
                serialized_name="privateEndpointConnections",
                flags={"read_only": True},
            )
            properties.provisioning_state = AAZStrType(
                serialized_name="provisioningState",
                flags={"read_only": True},
            )
            properties.public_network_access = AAZStrType(
                serialized_name="publicNetworkAccess",
            )
            properties.replica_count = AAZIntType(
                serialized_name="replicaCount",
            )
            properties.semantic_search = AAZStrType(
                serialized_name="semanticSearch",
                nullable=True,
            )
            properties.shared_private_link_resources = AAZListType(
                serialized_name="sharedPrivateLinkResources",
                flags={"read_only": True},
            )
            properties.status = AAZStrType(
                flags={"read_only": True},
            )
            properties.status_details = AAZStrType(
                serialized_name="statusDetails",
                flags={"read_only": True},
            )

            auth_options = cls._schema_on_200_201.properties.auth_options
            auth_options.aad_or_api_key = AAZObjectType(
                serialized_name="aadOrApiKey",
            )
            auth_options.api_key_only = AAZObjectType(
                serialized_name="apiKeyOnly",
            )

            aad_or_api_key = cls._schema_on_200_201.properties.auth_options.aad_or_api_key
            aad_or_api_key.aad_auth_failure_mode = AAZStrType(
                serialized_name="aadAuthFailureMode",
            )

            encryption_with_cmk = cls._schema_on_200_201.properties.encryption_with_cmk
            encryption_with_cmk.encryption_compliance_status = AAZStrType(
                serialized_name="encryptionComplianceStatus",
                flags={"read_only": True},
            )
            encryption_with_cmk.enforcement = AAZStrType()

            network_rule_set = cls._schema_on_200_201.properties.network_rule_set
            network_rule_set.ip_rules = AAZListType(
                serialized_name="ipRules",
            )

            ip_rules = cls._schema_on_200_201.properties.network_rule_set.ip_rules
            ip_rules.Element = AAZObjectType()

            _element = cls._schema_on_200_201.properties.network_rule_set.ip_rules.Element
            _element.value = AAZStrType()

            private_endpoint_connections = cls._schema_on_200_201.properties.private_endpoint_connections
            private_endpoint_connections.Element = AAZObjectType()

            _element = cls._schema_on_200_201.properties.private_endpoint_connections.Element
            _element.id = AAZStrType(
                flags={"read_only": True},
            )
            _element.name = AAZStrType(
                flags={"read_only": True},
            )
            _element.properties = AAZObjectType()
            _element.type = AAZStrType(
                flags={"read_only": True},
            )

            properties = cls._schema_on_200_201.properties.private_endpoint_connections.Element.properties
            properties.group_id = AAZStrType(
                serialized_name="groupId",
            )
            properties.private_endpoint = AAZObjectType(
                serialized_name="privateEndpoint",
            )
            properties.private_link_service_connection_state = AAZObjectType(
                serialized_name="privateLinkServiceConnectionState",
            )
            properties.provisioning_state = AAZStrType(
                serialized_name="provisioningState",
            )

            private_endpoint = cls._schema_on_200_201.properties.private_endpoint_connections.Element.properties.private_endpoint
            private_endpoint.id = AAZStrType()

            private_link_service_connection_state = cls._schema_on_200_201.properties.private_endpoint_connections.Element.properties.private_link_service_connection_state
            private_link_service_connection_state.actions_required = AAZStrType(
                serialized_name="actionsRequired",
            )
            private_link_service_connection_state.description = AAZStrType()
            private_link_service_connection_state.status = AAZStrType()

            shared_private_link_resources = cls._schema_on_200_201.properties.shared_private_link_resources
            shared_private_link_resources.Element = AAZObjectType()

            _element = cls._schema_on_200_201.properties.shared_private_link_resources.Element
            _element.id = AAZStrType(
                flags={"read_only": True},
            )
            _element.name = AAZStrType(
                flags={"read_only": True},
            )
            _element.properties = AAZObjectType()
            _element.type = AAZStrType(
                flags={"read_only": True},
            )

            properties = cls._schema_on_200_201.properties.shared_private_link_resources.Element.properties
            properties.group_id = AAZStrType(
                serialized_name="groupId",
            )
            properties.private_link_resource_id = AAZStrType(
                serialized_name="privateLinkResourceId",
            )
            properties.provisioning_state = AAZStrType(
                serialized_name="provisioningState",
            )
            properties.request_message = AAZStrType(
                serialized_name="requestMessage",
            )
            properties.resource_region = AAZStrType(
                serialized_name="resourceRegion",
            )
            properties.status = AAZStrType()

            sku = cls._schema_on_200_201.sku
            sku.name = AAZStrType(
                flags={"required": True},
            )

            tags = cls._schema_on_200_201.tags
            tags.Element = AAZStrType()

            return cls._schema_on_200_201


class _CreateHelper:
    """Helper class for Create"""


__all__ = ["Create"]
