# Copyright (C) 2019 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 webkitcorepy import BytesIO

import json
import requests
import sys
import time
import unittest

try:
    from collections.abc import Iterable, Mapping
except ImportError:
    from collections import Iterable, Mapping

from webkitpy.results.upload import Upload
from webkitpy.thirdparty import mock

if sys.version_info > (3, 0):
    basestring = str


class UploadTest(unittest.TestCase):

    class Options(object):
        def __init__(self, **kwargs):
            for key, value in kwargs.items():
                setattr(self, key, value)

    class MockResponse(object):
        def __init__(self, status_code=200, text=''):
            self.status_code = status_code
            self.text = text

        def json(self):
            return json.loads(self.text)

    @staticmethod
    def normalize(data):
        if isinstance(data, basestring):
            return str(data)
        elif isinstance(data, Mapping):
            return dict(map(UploadTest.normalize, data.items()))
        elif isinstance(data, Iterable):
            return type(data)(map(UploadTest.normalize, data))
        return data

    @staticmethod
    def raise_requests_ConnectionError():
        raise requests.exceptions.ConnectionError()

    def test_encoding(self):
        start_time, end_time = time.time() - 3, time.time()
        upload = Upload(
            suite='webkitpy-tests',
            configuration=Upload.create_configuration(
                platform='mac',
                version='10.13.0',
                version_name='High Sierra',
                architecture='x86_64',
                sdk='17A405',
            ),
            details=Upload.create_details(link='https://webkit.org'),
            commits=[Upload.create_commit(
                repository_id='webkit',
                id='5',
                branch='trunk',
            )],
            run_stats=Upload.create_run_stats(
                start_time=start_time,
                end_time=end_time,
                tests_skipped=0,
            ),
            results={
                'webkitpy.test1': {},
                'webkitpy.test2': Upload.create_test_result(expected=Upload.Expectations.PASS, actual=Upload.Expectations.FAIL),
            },
        )
        generated_dict = self.normalize(json.loads(json.dumps(upload, cls=Upload.Encoder)))

        self.assertEqual(generated_dict['version'], 0)
        self.assertEqual(generated_dict['suite'], 'webkitpy-tests')
        self.assertEqual(generated_dict['configuration'], self.normalize(dict(
            platform='mac',
            is_simulator=False,
            version='10.13.0',
            version_name='High Sierra',
            architecture='x86_64',
            sdk='17A405',
        )))
        self.assertEqual(generated_dict['commits'], [dict(
            repository_id='webkit',
            id='5',
            branch='trunk',
        )])
        self.assertEqual(generated_dict['test_results']['details'], self.normalize(dict(link='https://webkit.org')))
        self.assertEqual(generated_dict['test_results']['run_stats'], self.normalize(dict(
            start_time=start_time,
            end_time=end_time,
            tests_skipped=0,
        )))
        self.assertEqual(generated_dict['test_results']['results'], self.normalize({
            'webkitpy.test1': {},
            'webkitpy.test2': Upload.create_test_result(expected=Upload.Expectations.PASS, actual=Upload.Expectations.FAIL),
        }))

    def test_upload(self):
        upload = Upload(
            suite='webkitpy-tests',
            commits=[Upload.create_commit(
                repository_id='webkit',
                id='5',
                branch='trunk',
            )],
        )

        with mock.patch('requests.post', new=lambda url, headers={}, data={}, verify=True: self.MockResponse()):
            self.assertTrue(upload.upload('https://results.webkit.org', log_line_func=lambda _: None))

        with mock.patch('requests.post', new=lambda url, headers={}, data={}, verify=True: self.raise_requests_ConnectionError()):
            lines = []
            self.assertFalse(upload.upload('https://results.webkit.org', log_line_func=lambda line: lines.append(line)))
            self.assertEqual([' ' * 4 + 'Failed to upload to https://results.webkit.org, results server not online'], lines)

        mock_404 = mock.patch('requests.post', new=lambda url, headers={}, data={}, verify=True: self.MockResponse(
            status_code=404,
            text=json.dumps(dict(description='No such address')),
        ))
        with mock_404:
            self.assertFalse(upload.upload('https://results.webkit.org', log_line_func=lambda _: None))

    def test_packed_test(self):
        upload = Upload(
            suite='webkitpy-tests',
            commits=[Upload.create_commit(
                repository_id='webkit',
                id='5',
                branch='trunk',
            )],
            results={
                'dir1/sub-dir1/test1': Upload.create_test_result(actual=Upload.Expectations.FAIL),
                'dir1/sub-dir1/test2': Upload.create_test_result(actual=Upload.Expectations.TIMEOUT),
                'dir1/sub-dir2/test3': {},
                'dir1/sub-dir2/test4': {},
                'dir2/sub-dir3/test5': {},
                'dir2/test6': {},
            }
        )
        generated_dict = self.normalize(json.loads(json.dumps(upload, cls=Upload.Encoder)))
        self.assertEqual(generated_dict['test_results']['results'], self.normalize({
            'dir1': {
                'sub-dir1': {
                    'test1': {'actual': Upload.Expectations.FAIL},
                    'test2': {'actual': Upload.Expectations.TIMEOUT},
                }, 'sub-dir2': {
                    'test3': {},
                    'test4': {},
                }
            }, 'dir2': {
                'sub-dir3': {'test5': {}},
                'test6': {},
            },
        }))

    def test_no_suite(self):
        upload = Upload(
            commits=[Upload.create_commit(
                repository_id='webkit',
                id='5',
                branch='trunk',
            )],
        )
        with self.assertRaises(ValueError):
            json.dumps(upload, cls=Upload.Encoder)

    def test_no_commits(self):
        upload = Upload(
            suite='webkitpy-tests',
        )
        with self.assertRaises(ValueError):
            json.dumps(upload, cls=Upload.Encoder)

    def test_buildbot(self):
        upload = Upload(
            suite='webkitpy-tests',
            commits=[Upload.create_commit(
                repository_id='webkit',
                id='5',
                branch='trunk',
            )],
            details=Upload.create_details(options=self.Options(
                buildbot_master='webkit.org',
                builder_name='Queue-1',
                build_number=1,
        )))
        with self.assertRaises(ValueError):
            json.dumps(upload, cls=Upload.Encoder)

        upload.details['buildbot-worker'] = 'bot123'
        generated_dict = self.normalize(json.loads(json.dumps(upload, cls=Upload.Encoder)))
        self.assertEqual(generated_dict['test_results']['details'], self.normalize({
            'buildbot-master': 'webkit.org',
            'builder-name': 'Queue-1',
            'build-number': 1,
            'buildbot-worker': 'bot123',
        }))

    def test_archive_upload(self):
        upload = Upload(
            suite='webkitpy-tests',
            commits=[Upload.create_commit(
                repository_id='webkit',
                id='5',
                branch='trunk',
            )],
        )

        with mock.patch('requests.post', new=lambda url, headers={}, data={}, files={}, verify=True: self.MockResponse()):
            self.assertTrue(upload.upload_archive('https://results.webkit.org', archive=BytesIO(b'content'), log_line_func=lambda _: None))

        with mock.patch('requests.post', new=lambda url, headers={}, data={}, files={}, verify=True: self.raise_requests_ConnectionError()):
            lines = []
            self.assertTrue(upload.upload_archive('https://results.webkit.org', archive=BytesIO(b'content'), log_line_func=lambda line: lines.append(line)))
            self.assertEqual([
                ' ' * 4 + 'Failed to upload test archive to https://results.webkit.org, results server dropped connection, likely due to archive size (0.0 MB).',
                ' ' * 4 + 'This error is not fatal, continuing'
            ], lines)

        mock_404 = mock.patch('requests.post', new=lambda url, headers={}, data={}, files={}, verify=True: self.MockResponse(
            status_code=404,
            text=json.dumps(dict(description='No such address')),
        ))
        with mock_404:
            lines = []
            self.assertFalse(upload.upload_archive('https://results.webkit.org', archive='content', log_line_func=lambda line: lines.append(line)))
            self.assertEqual([
                ' ' * 4 + 'Error uploading archive to https://results.webkit.org',
                ' ' * 8 + 'No such address',
            ], lines)

        mock_413 = mock.patch('requests.post', new=lambda url, headers={}, data={}, files={}, verify=True: self.MockResponse(
            status_code=413,
            text=json.dumps(dict(description='Request Entity Too Large')),
        ))
        with mock_413:
            lines = []
            self.assertTrue(upload.upload_archive('https://results.webkit.org', archive='content', log_line_func=lambda line: lines.append(line)))
            self.assertEqual([
                ' ' * 4 + 'Upload to https://results.webkit.org failed:',
                ' ' * 8 + 'Request Entity Too Large',
                ' ' * 4 + 'This error is not fatal, continuing',
            ], lines)
