"""Init file for HassIO supervisor rest api."""
import asyncio
import logging

import voluptuous as vol

from .util import api_process, api_process_raw, api_validate
from ..addons.util import create_hash_index_list
from ..const import (
    ATTR_ADDONS, ATTR_VERSION, ATTR_LAST_VERSION, ATTR_BETA_CHANNEL,
    HASSIO_VERSION, ATTR_ADDONS_REPOSITORIES, ATTR_REPOSITORIES,
    ATTR_REPOSITORY, ATTR_DESCRIPTON, ATTR_NAME, ATTR_SLUG, ATTR_INSTALLED,
    ATTR_DETACHED, ATTR_SOURCE, ATTR_MAINTAINER, ATTR_URL)

_LOGGER = logging.getLogger(__name__)

SCHEMA_OPTIONS = vol.Schema({
    # pylint: disable=no-value-for-parameter
    vol.Optional(ATTR_BETA_CHANNEL): vol.Boolean(),
    vol.Optional(ATTR_ADDONS_REPOSITORIES): [vol.Url()],
})

SCHEMA_VERSION = vol.Schema({
    vol.Optional(ATTR_VERSION): vol.Coerce(str),
})


class APISupervisor(object):
    """Handle rest api for supervisor functions."""

    def __init__(self, config, loop, supervisor, addons, host_control):
        """Initialize supervisor rest api part."""
        self.config = config
        self.loop = loop
        self.supervisor = supervisor
        self.addons = addons
        self.host_control = host_control

    def _addons_list(self, only_installed=False):
        """Return a list of addons."""
        detached = self.addons.list_detached

        if only_installed:
            addons = self.addons.data_installed
        else:
            addons = self.addons.data_all

        data = []
        for addon, values in addons:
            i_version = self.addons.version_installed(addon)

            data.append({
                ATTR_NAME: values[ATTR_NAME],
                ATTR_SLUG: addon,
                ATTR_DESCRIPTON: values[ATTR_DESCRIPTON],
                ATTR_VERSION: values[ATTR_VERSION],
                ATTR_INSTALLED: i_version,
                ATTR_DETACHED: addon in detached,
                ATTR_REPOSITORY: values[ATTR_REPOSITORY],
            })

        return data

    def _repositories_list(self):
        """Return a list of addons repositories."""
        data = []
        list_id = create_hash_index_list(self.config.addons_repositories)

        for repository in self.addons.list_repositories:
            data.append({
                ATTR_SLUG: repository[ATTR_SLUG],
                ATTR_NAME: repository[ATTR_NAME],
                ATTR_SOURCE: list_id.get(repository[ATTR_SLUG]),
                ATTR_URL: repository.get(ATTR_URL),
                ATTR_MAINTAINER: repository.get(ATTR_MAINTAINER),
            })

        return data

    @api_process
    async def ping(self, request):
        """Return ok for signal that the api is ready."""
        return True

    @api_process
    async def info(self, request):
        """Return host information."""
        return {
            ATTR_VERSION: HASSIO_VERSION,
            ATTR_LAST_VERSION: self.config.last_hassio,
            ATTR_BETA_CHANNEL: self.config.upstream_beta,
            ATTR_ADDONS: self._addons_list(only_installed=True),
            ATTR_ADDONS_REPOSITORIES: self.config.addons_repositories,
        }

    @api_process
    async def available_addons(self, request):
        """Return information for all available addons."""
        return {
            ATTR_ADDONS: self._addons_list(),
            ATTR_REPOSITORIES: self._repositories_list(),
        }

    @api_process
    async def options(self, request):
        """Set supervisor options."""
        body = await api_validate(SCHEMA_OPTIONS, request)

        if ATTR_BETA_CHANNEL in body:
            self.config.upstream_beta = body[ATTR_BETA_CHANNEL]

        if ATTR_ADDONS_REPOSITORIES in body:
            new = set(body[ATTR_ADDONS_REPOSITORIES])
            old = set(self.config.addons_repositories)

            # add new repositories
            tasks = [self.addons.add_git_repository(url) for url in
                     set(new - old)]
            if tasks:
                await asyncio.shield(
                    asyncio.wait(tasks, loop=self.loop), loop=self.loop)

            # remove old repositories
            for url in set(old - new):
                self.addons.drop_git_repository(url)

            # read repository
            self.addons.read_data_from_repositories()

        return True

    @api_process
    async def update(self, request):
        """Update supervisor OS."""
        body = await api_validate(SCHEMA_VERSION, request)
        version = body.get(ATTR_VERSION, self.config.last_hassio)

        if version == self.supervisor.version:
            raise RuntimeError("Version is already in use")

        return await asyncio.shield(
            self.supervisor.update(version), loop=self.loop)

    @api_process
    async def reload(self, request):
        """Reload addons, config ect."""
        tasks = [
            self.addons.reload(), self.config.fetch_update_infos(),
            self.host_control.load()
        ]
        results, _ = await asyncio.shield(
            asyncio.wait(tasks, loop=self.loop), loop=self.loop)

        for result in results:
            if result.exception() is not None:
                raise RuntimeError("Some reload task fails!")

        return True

    @api_process_raw
    def logs(self, request):
        """Return supervisor docker logs.

        Return a coroutine.
        """
        return self.supervisor.logs()

@@ -1498,16 +1498,24 @@
 n addons
+.items()
 :%0A      

Fix bug