# coding=utf-8
# Copyright (c) 2015 EMC Corporation.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
from __future__ import unicode_literals

import logging
from unittest import TestCase

from hamcrest import equal_to, assert_that, not_none, none, raises

from storops.vnx.enums import VNXSPEnum
from storops.vnx.parsers import VNXCliParser, VNXPropDescriptor, \
    VNXParserConfigFactory
from storops.vnx.resource import get_vnx_parser
from storops_test.vnx.cli_mock import MockCli
from storops_test.vnx.resource.fakes import STORAGE_GROUP_HBA

log = logging.getLogger(__name__)

A = VNXPropDescriptor('-a', 'Prop A (name):', 'prop_a')
B = VNXPropDescriptor('-b', 'Prop B:')
C = VNXPropDescriptor('-c', 'Prop C:')
ID = VNXPropDescriptor(None, 'ID:', is_index=True)


class DemoParser(VNXCliParser):
    def __init__(self):
        super(DemoParser, self).__init__()
        self.add_property(A, B, C, ID)


class DemoParserNonIndex(VNXCliParser):
    def __init__(self):
        super(DemoParserNonIndex, self).__init__()
        self.add_property(VNXPropDescriptor('-b', 'Prop B:'))


class DemoParserRegexIndex(VNXCliParser):
    def __init__(self):
        super(DemoParserRegexIndex, self).__init__()
        self.add_property(
            VNXPropDescriptor(None,
                              r'\s*\w+:(\d+)',
                              'id',
                              is_index=True,
                              is_regex=True,
                              converter=int),
            VNXPropDescriptor(None,
                              r'\s*value:\s*(\w+)',
                              'value',
                              is_regex=True))


class DemoParserMultiIndices(VNXCliParser):
    def __init__(self):
        super(DemoParserMultiIndices, self).__init__()
        self.add_property(
            VNXPropDescriptor(None, 'A:', is_index=True),
            VNXPropDescriptor(None, 'B:', is_index=True),
            VNXPropDescriptor(None, 'C:'),
            VNXPropDescriptor(None, 'D:'))


class VNXCliParserTest(TestCase):
    def test_get_property_options(self):
        options = DemoParser().property_options
        assert_that(' '.join(options), equal_to('-a -b -c'))

    def test_get_index_descriptor(self):
        assert_that(DemoParser().index_property.label, equal_to('ID:'))

    def test_get_index_descriptor_none(self):
        assert_that(DemoParserNonIndex().index_property, none())

    def test_parse(self):
        output = """
                ID: test
                Prop A (Name): ab (c)
                Prop B: d ef
                """
        parser = DemoParser()
        parsed = parser.parse(output, [A, ID, C])

        assert_that(parsed.prop_a, equal_to('ab (c)'))
        assert_that(parsed.prop_c, none())
        assert_that(parsed.id, equal_to('test'))

        def f():
            log.debug(parsed.prop_b)

        assert_that(f, raises(AttributeError))

    def test_parse_empty_prop(self):
        output = """
                ID: test
                Prop A (Name): ab (c)
                Prop B:
                Prop C: abc
                """
        parser = DemoParser()
        parsed = parser.parse(output, [A, ID, B, C])

        assert_that(parsed.id, equal_to('test'))
        assert_that(parsed.prop_a, equal_to('ab (c)'))
        assert_that(parsed.prop_b, equal_to(''))

    def test_parse_regex_label(self):
        output = """
                id:123
                value:abcde
                id:456
                value:ghijk
                """
        parsed = DemoParserRegexIndex().parse_all(output)
        assert_that(len(parsed), equal_to(2))
        for i in parsed:
            if i.id == 123:
                assert_that(i.value, equal_to('abcde'))
            elif i.id == 456:
                assert_that(i.value, equal_to('ghijk'))
            else:
                self.fail('id not recognized.')

    def test_all_options(self):
        options = DemoParser().all_options
        assert_that(options, equal_to(['-a', '-b', '-c']))

    def test_parse_multi_index(self):
        output = """
        A: a0
        B: b0
        C: c0

        A: a0
        B: b0
        D: d0

        A: a0
        B: b1
        C: c1
        """
        parsed = DemoParserMultiIndices().parse_all(output)
        assert_that(len(parsed), equal_to(2))
        a0b0 = next(i for i in parsed if i.b == 'b0')
        assert_that(a0b0, not_none())
        assert_that(a0b0.a, equal_to('a0'))
        assert_that(a0b0.b, equal_to('b0'))
        assert_that(a0b0.c, equal_to('c0'))
        assert_that(a0b0.d, equal_to('d0'))