"""Component to integrate the Home Assistant cloud."""
import logging

from hass_nabucasa import Cloud
import voluptuous as vol

from homeassistant.auth.const import GROUP_ID_ADMIN
from homeassistant.components.alexa import const as alexa_const
from homeassistant.components.google_assistant import const as ga_c
from homeassistant.const import (
    CONF_MODE,
    CONF_NAME,
    CONF_REGION,
    EVENT_HOMEASSISTANT_START,
    EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv, entityfilter
from homeassistant.loader import bind_hass
from homeassistant.util.aiohttp import MockRequest

from . import account_link, http_api
from .client import CloudClient
from .const import (
    CONF_ACCOUNT_LINK_URL,
    CONF_ACME_DIRECTORY_SERVER,
    CONF_ALEXA,
    CONF_ALEXA_ACCESS_TOKEN_URL,
    CONF_ALIASES,
    CONF_CLOUDHOOK_CREATE_URL,
    CONF_COGNITO_CLIENT_ID,
    CONF_ENTITY_CONFIG,
    CONF_FILTER,
    CONF_GOOGLE_ACTIONS,
    CONF_GOOGLE_ACTIONS_REPORT_STATE_URL,
    CONF_GOOGLE_ACTIONS_SYNC_URL,
    CONF_RELAYER,
    CONF_REMOTE_API_URL,
    CONF_SUBSCRIPTION_INFO_URL,
    CONF_USER_POOL_ID,
    CONF_VOICE_API_URL,
    DOMAIN,
    MODE_DEV,
    MODE_PROD,
)
from .prefs import CloudPreferences

_LOGGER = logging.getLogger(__name__)

DEFAULT_MODE = MODE_PROD

SERVICE_REMOTE_CONNECT = "remote_connect"
SERVICE_REMOTE_DISCONNECT = "remote_disconnect"


ALEXA_ENTITY_SCHEMA = vol.Schema(
    {
        vol.Optional(alexa_const.CONF_DESCRIPTION): cv.string,
        vol.Optional(alexa_const.CONF_DISPLAY_CATEGORIES): cv.string,
        vol.Optional(CONF_NAME): cv.string,
    }
)

GOOGLE_ENTITY_SCHEMA = vol.Schema(
    {
        vol.Optional(CONF_NAME): cv.string,
        vol.Optional(CONF_ALIASES): vol.All(cv.ensure_list, [cv.string]),
        vol.Optional(ga_c.CONF_ROOM_HINT): cv.string,
    }
)

ASSISTANT_SCHEMA = vol.Schema(
    {vol.Optional(CONF_FILTER, default=dict): entityfilter.FILTER_SCHEMA}
)

ALEXA_SCHEMA = ASSISTANT_SCHEMA.extend(
    {vol.Optional(CONF_ENTITY_CONFIG): {cv.entity_id: ALEXA_ENTITY_SCHEMA}}
)

GACTIONS_SCHEMA = ASSISTANT_SCHEMA.extend(
    {vol.Optional(CONF_ENTITY_CONFIG): {cv.entity_id: GOOGLE_ENTITY_SCHEMA}}
)

# pylint: disable=no-value-for-parameter
CONFIG_SCHEMA = vol.Schema(
    {
        DOMAIN: vol.Schema(
            {
                vol.Optional(CONF_MODE, default=DEFAULT_MODE): vol.In(
                    [MODE_DEV, MODE_PROD]
                ),
                vol.Optional(CONF_COGNITO_CLIENT_ID): str,
                vol.Optional(CONF_USER_POOL_ID): str,
                vol.Optional(CONF_REGION): str,
                vol.Optional(CONF_RELAYER): str,
                vol.Optional(CONF_GOOGLE_ACTIONS_SYNC_URL): vol.Url(),
                vol.Optional(CONF_SUBSCRIPTION_INFO_URL): vol.Url(),
                vol.Optional(CONF_CLOUDHOOK_CREATE_URL): vol.Url(),
                vol.Optional(CONF_REMOTE_API_URL): vol.Url(),
                vol.Optional(CONF_ACME_DIRECTORY_SERVER): vol.Url(),
                vol.Optional(CONF_ALEXA): ALEXA_SCHEMA,
                vol.Optional(CONF_GOOGLE_ACTIONS): GACTIONS_SCHEMA,
                vol.Optional(CONF_ALEXA_ACCESS_TOKEN_URL): vol.Url(),