# coding: utf-8
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.

from __future__ import absolute_import

from oci._vendor import requests  # noqa: F401
from oci._vendor import six

from oci import retry  # noqa: F401
from oci.base_client import BaseClient
from oci.config import get_config_value_or_default, validate_config
from oci.signer import Signer
from oci.util import Sentinel
from .models import mysql_type_mapping
missing = Sentinel("Missing")


class LimitsChecksClient(object):
    """
    The API for the MySQL Service
    """

    def __init__(self, config, **kwargs):
        """
        Creates a new service client

        :param dict config:
            Configuration keys and values as per `SDK and Tool Configuration <https://docs.cloud.oracle.com/Content/API/Concepts/sdkconfig.htm>`__.
            The :py:meth:`~oci.config.from_file` method can be used to load configuration from a file. Alternatively, a ``dict`` can be passed. You can validate_config
            the dict using :py:meth:`~oci.config.validate_config`

        :param str service_endpoint: (optional)
            The endpoint of the service to call using this client. For example ``https://iaas.us-ashburn-1.oraclecloud.com``. If this keyword argument is
            not provided then it will be derived using the region in the config parameter. You should only provide this keyword argument if you have an explicit
            need to specify a service endpoint.

        :param timeout: (optional)
            The connection and read timeouts for the client. The default is that the client never times out. This keyword argument can be provided
            as a single float, in which case the value provided is used for both the read and connection timeouts, or as a tuple of two floats. If
            a tuple is provided then the first value is used as the connection timeout and the second value as the read timeout.
        :type timeout: float or tuple(float, float)

        :param signer: (optional)
            The signer to use when signing requests made by the service client. The default is to use a :py:class:`~oci.signer.Signer` based on the values
            provided in the config parameter.

            One use case for this parameter is for `Instance Principals authentication <https://docs.cloud.oracle.com/Content/Identity/Tasks/callingservicesfrominstances.htm>`__
            by passing an instance of :py:class:`~oci.auth.signers.InstancePrincipalsSecurityTokenSigner` as the value for this keyword argument
        :type signer: :py:class:`~oci.signer.AbstractBaseSigner`

        :param obj retry_strategy: (optional)
            A retry strategy to apply to all calls made by this service client (i.e. at the client level). There is no retry strategy applied by default.
            Retry strategies can also be applied at the operation level by passing a ``retry_strategy`` keyword argument as part of calling the operation.
            Any value provided at the operation level will override whatever is specified at the client level.

            This should be one of the strategies available in the :py:mod:`~oci.retry` module. A convenience :py:data:`~oci.retry.DEFAULT_RETRY_STRATEGY`
            is also available. The specifics of the default retry strategy are described `here <https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/sdk_behaviors/retries.html>`__.
        """
        validate_config(config, signer=kwargs.get('signer'))
        if 'signer' in kwargs:
            signer = kwargs['signer']
        else:
            signer = Signer(
                tenancy=config["tenancy"],
                user=config["user"],
                fingerprint=config["fingerprint"],
                private_key_file_location=config.get("key_file"),
                pass_phrase=get_config_value_or_default(config, "pass_phrase"),
                private_key_content=config.get("key_content")
            )

        base_client_init_kwargs = {
            'regional_client': True,
            'service_endpoint': kwargs.get('service_endpoint'),
            'timeout': kwargs.get('timeout'),
            'base_path': '/20190415',
            'service_endpoint_template': 'https://mysql.{region}.ocp.{secondLevelDomain}',
            'skip_deserialization': kwargs.get('skip_deserialization', False)
        }
        self.base_client = BaseClient("limits_checks", config, signer, mysql_type_mapping, **base_client_init_kwargs)
        self.retry_strategy = kwargs.get('retry_strategy')

    def get_mysqlaas_instance_limits_check(self, db_system_id, compartment_id, availability_domain, shape_name, data_storage_size_in_gbs, **kwargs):
        """
        Checks resource limits for a MySQLaaS Instance.
        Gets an object that is either empty or describes an error (if there are not enough available resources to launch a MySQLaaS
        Instance), according to the given instance details. It does not reserve the resources, just provides a way to
        fail fast if there are no resources at the moment, not preventing the case of concurrent launches that will pass
        the checks and fail later because resources are no longer available when actually launching the instances.


        :param str db_system_id: (required)
            OCID of the MySQL DbSystem that we are trying to create. The DbSystem does not exist yet, so this
            is just for logging purposes. The id will only be valid if the check passes.

        :param str compartment_id: (required)

        :param str availability_domain: (required)
            The Availability Domain where the MySQLaaS instance is going to be located.

        :param str shape_name: (required)

        :param int data_storage_size_in_gbs: (required)

        :param str opc_request_id: (optional)
            Customer-defined unique identifier for the request. If you need to
            contact Oracle about a specific request, please provide the request
            ID that you supplied in this header with the request.

        :param str analytics_shape_name: (optional)
            The shape determines resources to allocate to the MySQLaaS Analyics
            Cluster nodes - CPU cores, memory.

        :param int analytics_cluster_size: (optional)
            The number of analytics-processing nodes provisioned for the
            MySQLaaS Analytics Cluster.

        :param obj retry_strategy: (optional)
            A retry strategy to apply to this specific operation/call. This will override any retry strategy set at the client-level.

            This should be one of the strategies available in the :py:mod:`~oci.retry` module. A convenience :py:data:`~oci.retry.DEFAULT_RETRY_STRATEGY`
            is also available. The specifics of the default retry strategy are described `here <https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/sdk_behaviors/retries.html>`__.

            To have this operation explicitly not perform any retries, pass an instance of :py:class:`~oci.retry.NoneRetryStrategy`.

        :return: A :class:`~oci.response.Response` object with data of type :class:`~oci.mysql.models.MysqlaasInstanceLimitsCheck`
        :rtype: :class:`~oci.response.Response`
        """
        resource_path = "/limits/mysqlaasInstance"
        method = "GET"

        # Don't accept unknown kwargs
        expected_kwargs = [
            "retry_strategy",
            "opc_request_id",
            "analytics_shape_name",
            "analytics_cluster_size"
        ]
        extra_kwargs = [_key for _key in six.iterkeys(kwargs) if _key not in expected_kwargs]
        if extra_kwargs:
            raise ValueError(
                "get_mysqlaas_instance_limits_check got unknown kwargs: {!r}".format(extra_kwargs))

        query_params = {
            "dbSystemId": db_system_id,
            "compartmentId": compartment_id,
            "availabilityDomain": availability_domain,
            "shapeName": shape_name,
            "dataStorageSizeInGBs": data_storage_size_in_gbs,
            "analyticsShapeName": kwargs.get("analytics_shape_name", missing),
            "analyticsClusterSize": kwargs.get("analytics_cluster_size", missing)
        }
        query_params = {k: v for (k, v) in six.iteritems(query_params) if v is not missing and v is not None}

        header_params = {
            "accept": "application/json",
            "content-type": "application/json",
            "opc-request-id": kwargs.get("opc_request_id", missing)
        }
        header_params = {k: v for (k, v) in six.iteritems(header_params) if v is not missing and v is not None}

        retry_strategy = self.retry_strategy
        if kwargs.get('retry_strategy'):
            retry_strategy = kwargs.get('retry_strategy')

        if retry_strategy:
            return retry_strategy.make_retrying_call(
                self.base_client.call_api,
                resource_path=resource_path,
                method=method,
                query_params=query_params,
                header_params=header_params,
                response_type="MysqlaasInstanceLimitsCheck")
        else:
            return self.base_client.call_api(
                resource_path=resource_path,
                method=method,
                query_params=query_params,
                header_params=header_params,
                response_type="MysqlaasInstanceLimitsCheck")
