"""Test the translation helper."""
# pylint: disable=protected-access
from os import path
from unittest.mock import patch

import pytest

import homeassistant.helpers.translation as translation
from homeassistant.setup import async_setup_component
from homeassistant.generated import config_flows
from tests.common import mock_coro


@pytest.fixture
def mock_config_flows():
    """Mock the config flows."""
    flows = []
    with patch.object(config_flows, 'FLOWS', flows):
        yield flows


def test_flatten():
    """Test the flatten function."""
    data = {
        "parent1": {
            "child1": "data1",
            "child2": "data2",
        },
        "parent2": "data3",
    }

    flattened = translation.flatten(data)

    assert flattened == {
        "parent1.child1": "data1",
        "parent1.child2": "data2",
        "parent2": "data3",
    }


async def test_component_translation_file(hass):
    """Test the component translation file function."""
    assert await async_setup_component(hass, 'switch', {
        'switch': [
            {'platform': 'test'},
            {'platform': 'test_embedded'}
        ]
    })
    assert await async_setup_component(hass, 'test_standalone', {
        'test_standalone'
    })
    assert await async_setup_component(hass, 'test_package', {
        'test_package'
    })

    assert path.normpath(await translation.component_translation_file(
        hass, 'switch.test', 'en')) == path.normpath(hass.config.path(
            'custom_components', 'test', '.translations', 'switch.en.json'))

    assert path.normpath(await translation.component_translation_file(
        hass, 'switch.test_embedded', 'en')) == path.normpath(hass.config.path(
            'custom_components', 'test_embedded', '.translations',
            'switch.en.json'))

    assert await translation.component_translation_file(
        hass, 'test_standalone', 'en'
    ) is None

    assert path.normpath(await translation.component_translation_file(
        hass, 'test_package', 'en')) == path.normpath(hass.config.path(
            'custom_components', 'test_package', '.translations', 'en.json'))


def test_load_translations_files(hass):
    """Test the load translation files function."""
    # Test one valid and one invalid file
    file1 = hass.config.path(
        'custom_components', 'test', '.translations', 'switch.en.json')
    file2 = hass.config.path(
        'custom_components', 'test', '.translations', 'invalid.json')
    assert translation.load_translations_files({
        'switch.test': file1,
        'invalid': file2
    }) == {
        'switch.test': {
            'state': {
                'string1': 'Value 1',
                'string2': 'Value 2',
            }
        },
        'invalid': {},
    }


async def test_get_translations(hass, mock_config_flows):
    """Test the get translations helper."""
    translations = await translation.async_get_translations(hass, 'en')
    assert translations == {}

    assert await async_setup_component(hass, 'switch', {
        'switch': {'platform': 'test'}
    })

    translations = await translation.async_get_translations(hass, 'en')
    assert translations == {
        'component.switch.state.string1': 'Value 1',
        'component.switch.state.string2': 'Value 2',
    }

    translations = await translation.async_get_translations(hass, 'de')
    assert translations == {
        'component.switch.state.string1': 'German Value 1',
        'component.switch.state.string2': 'German Value 2',
    }

    # Test a partial translation
    translations = await translation.async_get_translations(hass, 'es')
    assert translations == {
        'component.switch.state.string1': 'Spanish Value 1',
        'component.switch.state.string2': 'Value 2',
    }

    # Test that an untranslated language falls back to English.
    translations = await translation.async_get_translations(
        hass, 'invalid-language')
    assert translations == {
        'component.switch.state.string1': 'Value 1',
        'component.switch.state.string2': 'Value 2',
    }


async def test_get_translations_loads_config_flows(hass, mock_config_flows):
    """Test the get translations helper loads config flow translations."""
    mock_config_flows.append('component1')

    with patch.object(translation, 'component_translation_file',
                      return_value=mock_coro('bla.json')), \
            patch.object(translation, 'load_translations_files', return_value={
                'component1': {'hello': 'world'}}):
        translations = await translation.async_get_translations(hass, 'en')
    assert translations == {
        'component.component1.hello': 'world'
    }