# Copyright (C) 2021 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from webkitbugspy import User
from webkitcorepy import mocks


class Base(mocks.Requests):
    @classmethod
    def transform_user(cls, user):
        return User(
            name=user.name,
            username=user.username,
            emails=user.emails,
        )

    def __init__(self, *hosts, **kwargs):
        super(Base, self).__init__(*hosts)

        users = kwargs.get('users', None)
        issues = kwargs.get('issues', None)

        self.users = User.Mapping()
        for user in users or []:
            self.users.add(type(self).transform_user(user))

        self.issues = {}
        for issue in issues or []:
            self.add(issue)

    def add(self, bug_data):
        if not isinstance(bug_data, dict):
            raise ValueError('Expected bug data to be dictionary')

        id = bug_data.get('id')
        if not id:
            id = 1
            while id in self.issues:
                id += 1
            bug_data['id'] = id

        for user in [bug_data.get('creator'), bug_data.get('assignee')] + bug_data.get('watchers', []):
            if user:
                self.users.add(type(self).transform_user(user))

        self.issues[id] = {key: value for key, value in bug_data.items()}
