# Copyright (C) 2019, 2022 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.

import calendar
import datetime
import json
import os
import time
import twisted

from base64 import b64encode
from buildbot.process.results import SUCCESS, FAILURE, CANCELLED, WARNINGS, SKIPPED, EXCEPTION, RETRY
from buildbot.util import service
from buildbot.www.hooks.github import GitHubEventHandler
from steps import GitHub
from twisted.internet import defer
from twisted.internet import reactor
from twisted.internet.defer import succeed
from twisted.python import log
from twisted.web.client import Agent
from twisted.web.http_headers import Headers
from twisted.web.iweb import IBodyProducer
from zope.interface import implementer

custom_suffix = '-uat' if os.getenv('BUILDBOT_UAT') else ''

@implementer(IBodyProducer)
class JSONProducer(object):
    """
    Perform JSON asynchronously as to not lock the buildbot main event loop
    """

    def __init__(self, data):
        try:
            self.body = json.dumps(data, default=self.json_serialize_datetime).encode('utf-8')
        except TypeError:
            self.body = ''
        self.length = len(self.body)

    def startProducing(self, consumer):
        if self.body:
            consumer.write(self.body)
        return succeed(None)

    def pauseProducing(self):
        pass

    def stopProducing(self):
        pass

    def json_serialize_datetime(self, obj):
        """
        Serializing buildbot dates into UNIX epoch timestamps.
        """
        if isinstance(obj, datetime.datetime):
            return int(calendar.timegm(obj.timetuple()))

        raise TypeError("Type %s not serializable" % type(obj))


class Events(service.BuildbotService):

    EVENT_SERVER_ENDPOINT = 'https://ews.webkit{}.org/results/'.format(custom_suffix).encode()
    MAX_GITHUB_DESCRIPTION = 140

    def __init__(self, master_hostname, type_prefix='', name='Events'):
        """
        Initialize the Events Plugin. Sends data to event server on specific buildbot events.
        :param type_prefix: [optional] prefix we want to add to the 'type' field on the json we send
         to event server. (i.e. ews-build, where 'ews-' is the prefix.
        :return: Events Object
        """
        service.BuildbotService.__init__(self, name=name)

        if type_prefix and not type_prefix.endswith("-"):
            type_prefix += "-"
        self.type_prefix = type_prefix
        self.master_hostname = master_hostname

    def sendDataToEWS(self, data):
        if os.getenv('EWS_API_KEY', None):
            data['EWS_API_KEY'] = os.getenv('EWS_API_KEY')
        agent = Agent(reactor)
        body = JSONProducer(data)

        agent.request(b'POST', self.EVENT_SERVER_ENDPOINT, Headers({'Content-Type': ['application/json']}), body)

    def sendDataToGitHub(self, repository, sha, data):
        username, access_token = GitHub.credentials()

        data['description'] = data.get('description', '')
        if len(data['description']) > self.MAX_GITHUB_DESCRIPTION:
            data['description'] = '{}...'.format(data['description'][:self.MAX_GITHUB_DESCRIPTION - 3])

        auth_header = b64encode('{}:{}'.format(username, access_token).encode('utf-8')).decode('utf-8')

        agent = Agent(reactor)
        body = JSONProducer(data)
        d = agent.request(b'POST', GitHub.commit_status_url(sha, repository).encode('utf-8'), Headers({
            'Authorization': ['Basic {}'.format(auth_header)],
            'User-Agent': ['python-twisted/{}'.format(twisted.__version__)],
            'Accept': ['application/vnd.github.v3+json'],
            'Content-Type': ['application/json'],
        }), body)

    def getBuilderName(self, build):
        if not (build and 'properties' in build):
            return ''

        return build.get('properties').get('buildername')[0]

    def extractProperty(self, build, property_name):
        if not (build and 'properties' in build and property_name in build['properties']):
            return None

        return build.get('properties').get(property_name)[0]

    @defer.inlineCallbacks
    def buildStarted(self, key, build):
        if not build.get('properties'):
            build['properties'] = yield self.master.db.builds.getBuildProperties(build.get('buildid'))

        builder = yield self.master.db.builders.getBuilder(build.get('builderid'))
        builder_display_name = builder.get('description')

        data = {
            "type": self.type_prefix + "build",
            "status": "started",
            "hostname": self.master_hostname,
            "patch_id": self.extractProperty(build, 'patch_id'),
            "build_id": build.get('buildid'),
            "builder_id": build.get('builderid'),
            "number": build.get('number'),
            "result": build.get('results'),
            "started_at": build.get('started_at'),
            "complete_at": build.get('complete_at'),
            "state_string": build.get('state_string'),
            "builder_name": self.getBuilderName(build),
            "builder_display_name": builder_display_name,
        }

        self.sendDataToEWS(data)

    @defer.inlineCallbacks
    def buildFinishedGitHub(self, context, build):
        sha = self.extractProperty(build, 'github.head.sha')
        repository = self.extractProperty(build, 'repository')

        if not sha or not repository:
            print('Pull request number defined, but sha is {} and repository {}, which are invalid'.format(sha, repository))
            print('Not reporting build result to GitHub')
            return

        data_to_send = dict(
            owner=(self.extractProperty(build, 'owners') or [None])[0],
            repo=(self.extractProperty(build, 'github.head.repo.full_name') or '').split('/')[-1],
            sha=sha,
            target_url='{}#/builders/{}/builds/{}'.format(self.master.config.buildbotURL, build.get('builderid'), build.get('number')),
            state={
                SUCCESS: 'success',
                WARNINGS: 'success',
                SKIPPED: 'success',
                RETRY: 'pending',
                FAILURE: 'failure'
            }.get(build.get('results'), 'error'),
            description=build.get('state_string'),
            context=context,
        )
        self.sendDataToGitHub(repository, sha, data_to_send)

    @defer.inlineCallbacks
    def buildFinished(self, key, build):
        if not build.get('properties'):
            build['properties'] = yield self.master.db.builds.getBuildProperties(build.get('buildid'))
        if not build.get('steps'):
            build['steps'] = yield self.master.db.steps.getSteps(build.get('buildid'))

        builder = yield self.master.db.builders.getBuilder(build.get('builderid'))
        builder_display_name = builder.get('description')

        if self.extractProperty(build, 'github.number'):
            return self.buildFinishedGitHub(builder_display_name, build)

        patch_id = self.extractProperty(build, 'patch_id')
        if not patch_id:
            return

        data = {
            "type": self.type_prefix + "build",
            "status": "finished",
            "hostname": self.master_hostname,
            "patch_id": self.extractProperty(build, 'patch_id'),
            "build_id": build.get('buildid'),
            "builder_id": build.get('builderid'),
            "number": build.get('number'),
            "result": build.get('results'),
            "started_at": build.get('started_at'),
            "complete_at": build.get('complete_at'),
            "state_string": build.get('state_string'),
            "builder_name": self.getBuilderName(build),
            "builder_display_name": builder_display_name,
            "steps": build.get('steps'),
        }

        self.sendDataToEWS(data)

    @defer.inlineCallbacks
    def stepStartedGitHub(self, build, state_string):
        sha = self.extractProperty(build, 'github.head.sha')
        repository = self.extractProperty(build, 'repository')
        if not sha or not repository:
            print('Pull request number defined, but sha is {} and repository {}, which are invalid'.format(sha, repository))
            print('Not reporting step started to GitHub')
            return

        builder = yield self.master.db.builders.getBuilder(build.get('builderid'))

        data_to_send = dict(
            owner=(self.extractProperty(build, 'owners') or [None])[0],
            repo=(self.extractProperty(build, 'github.head.repo.full_name') or '').split('/')[-1],
            sha=sha,
            target_url='{}#/builders/{}/builds/{}'.format(self.master.config.buildbotURL, build.get('builderid'), build.get('number')),
            state={
                SUCCESS: 'pending',
                WARNINGS: 'pending',
                FAILURE: 'failure',
                EXCEPTION: 'error',
            }.get(build.get('results'), 'pending'),
            description=state_string,
            context=builder.get('description'),
        )
        self.sendDataToGitHub(repository, sha, data_to_send)

    @defer.inlineCallbacks
    def stepStarted(self, key, step):
        state_string = step.get('state_string')
        if state_string == 'pending':
            state_string = 'Running {}'.format(step.get('name'))

        build = yield self.master.db.builds.getBuild(step.get('buildid'))
        if not build.get('properties'):
            build['properties'] = yield self.master.db.builds.getBuildProperties(step.get('buildid'))

        # We need to force the defered properties to resolve
        if build['properties'].get('github.number'):
            self.stepStartedGitHub(build, state_string)

        data = {
            "type": self.type_prefix + "step",
            "status": "started",
            "hostname": self.master_hostname,
            "step_id": step.get('stepid'),
            "build_id": step.get('buildid'),
            "result": step.get('results'),
            "state_string": state_string,
            "started_at": step.get('started_at'),
            "complete_at": step.get('complete_at'),
        }

        self.sendDataToEWS(data)

    def stepFinished(self, key, step):
        data = {
            "type": self.type_prefix + "step",
            "status": "finished",
            "hostname": self.master_hostname,
            "step_id": step.get('stepid'),
            "build_id": step.get('buildid'),
            "result": step.get('results'),
            "state_string": step.get('state_string'),
            "started_at": step.get('started_at'),
            "complete_at": step.get('complete_at'),
        }

        self.sendDataToEWS(data)

    @defer.inlineCallbacks
    def startService(self):
        yield service.BuildbotService.startService(self)

        startConsuming = self.master.mq.startConsuming

        self._buildStartedConsumer = yield startConsuming(self.buildStarted, ('builds', None, 'new'))
        self._buildCompleteConsumer = yield startConsuming(self.buildFinished, ('builds', None, 'finished'))
        self._stepStartedConsumer = yield startConsuming(self.stepStarted, ('steps', None, 'started'))
        self._stepFinishedConsumer = yield startConsuming(self.stepFinished, ('steps', None, 'finished'))

    def stopService(self):
        self._buildStartedConsumer.stopConsuming()
        self._buildCompleteConsumer.stopConsuming()
        self._stepStartedConsumer.stopConsuming()
        self._stepFinishedConsumer.stopConsuming()


class GitHubEventHandlerNoEdits(GitHubEventHandler):
    ACTIONS_TO_TRIGGER_EWS = ('opened', 'synchronize')

    def _get_commit_msg(self, repo, sha):
        return ''

    def handle_pull_request(self, payload, event):
        pr_number = payload['number']
        action = payload.get('action')
        if action not in self.ACTIONS_TO_TRIGGER_EWS:
            log.msg('Action {} on PR #{} does not indicate code has been changed'.format(action, pr_number))
            return ([], 'git')
        return super(GitHubEventHandlerNoEdits, self).handle_pull_request(payload, event)
