# encoding: utf-8
"""
Copyright (c) [2022] [sanmejie]
[Software Name] is licensed under the Mulan PSL v1.
You can use this software according to the terms and conditions of the Mulan PSL v1.
You may obtain a copy of Mulan PSL v1 at:
    http://license.coscl.org.cn/MulanPSL
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
PURPOSE.
See the Mulan PSL v1 for more details.
"""
from .item import Item, camel, snake


class GetMixIn:

    def get(self, name):
        for item in self:
            if item.name == name:
                return item
        return None


class ResultBase:

    def __init__(self, raw):
        self.raw = raw

    def __getattr__(self, name):
        camel_name = camel(name)
        if camel_name in self.raw:
            return self.raw[camel_name]
        return super().__getattribute__(name)

    def __str__(self):
        return f'<{type(self).__name__}: {self.name}>'

    def __dir__(self):
        return super().__dir__() + [snake(k) for k in self.raw]


class TestReport(Item, GetMixIn):

    def __iter__(self):
        for suite in self.api_json()['suites']:
            yield TestSuite(suite)

    @property
    def suites(self):
        yield from self


class TestSuite(ResultBase, GetMixIn):

    def __iter__(self):
        for case in self.raw['cases']:
            yield TestCase(case)

    @property
    def cases(self):
        yield from self


class TestCase(ResultBase):
    pass


class CoverageReport(Item, GetMixIn):
    '''Access coverage report generated by `JaCoCo <https://plugins.jenkins.io/jacoco/>`_'''

    report_types = ['branchCoverage', 'classCoverage', 'complexityScore',
                    'instructionCoverage', 'lineCoverage', 'methodCoverage']

    def __getattr__(self, name):
        attr = camel(name)
        if attr not in self.report_types:
            raise AttributeError(
                f"'CoverageReport' object has no attribute '{name}'")
        return self.get(attr)

    def __iter__(self):
        for k, v in self.api_json().items():
            if k != '_class' and k != 'previousResult':
                v['name'] = k
                yield Coverage(v)

    def trends(self, count=2):
        def _resolve(data):
            if data['previousResult']:
                yield from _resolve(data['previousResult'])
            for k, v in data.items():
                if k != '_class' and k != 'previousResult':
                    v['name'] = k
                    yield Coverage(v)

        yield from _resolve(self.api_json(depth=count))


class Coverage(ResultBase):
    pass


class CoverageResult(Item, GetMixIn):
    '''Access coverage result generated by `Code Coverage API <https://plugins.jenkins.io/code-coverage-api/>`_'''

    def __iter__(self):
        for element in self.api_json(depth=1)['results']['elements']:
            yield CoverageElement(element)


class CoverageElement(ResultBase):
    pass


class CoverageTrends(Item, GetMixIn):
    def __iter__(self):
        for trend in self.api_json(depth=1)['trends']:
            trend['name'] = trend['buildName']
            yield CoverageTrend(trend)


class CoverageTrend(ResultBase):

    def __iter__(self):
        for element in self.raw['elements']:
            yield CoverageElement(element)
