# Copyright 2014 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for gob_util.py"""

import base64
import http.client
import json
import tempfile
import time
import urllib.request

from chromite.lib import config_lib
from chromite.lib import cros_test_lib
from chromite.lib import gob_util
from chromite.lib import timeout_util


gob_util.TRY_LIMIT = 1


class FakeHTTPResponse(object):
    """Enough of a HTTPResponse for FetchUrl.

    See https://docs.python.org/3/library/http.client.html#httpresponse-objects
    for more details.
    """

    def __init__(
        self, body=b"", headers=(), reason=None, status=200, version=11
    ):
        if reason is None:
            reason = http.client.responses[status]

        self.body = body
        self.headers = dict(headers)
        self.msg = None
        self.reason = reason
        self.status = status
        self.version = version

    def read(self):
        return self.body

    def getheader(self, name, default=None):
        return self.headers.get(name, default)

    def getheaders(self):
        return tuple(self.headers.items())


class GobTest(cros_test_lib.MockTestCase):
    """Unittests that use mocks."""

    UTF8_DATA = b"That\xe2\x80\x99s an error. That\xe2\x80\x99s all we know."

    def setUp(self):
        self.PatchObject(gob_util, "CreateHttpReq", autospec=False)
        self.conn = self.PatchObject(urllib.request, "urlopen")

    def testUtf8Response(self):
        """Handle gerrit responses w/UTF8 in them."""
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body=self.UTF8_DATA
        )
        gob_util.FetchUrl("", "")

    def testUtf8Response502(self):
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body=self.UTF8_DATA, status=502
        )

        with self.assertRaises(gob_util.InternalGOBError):
            gob_util.FetchUrl("", "")

    def testConnectionTimeout(self):
        """Exercise the timeout process."""
        # To finish the test quickly, we need to shorten the timeout.
        self.PatchObject(gob_util, "REQUEST_TIMEOUT_SECONDS", 1)

        # Setup a 'hanging' network connection.
        def simulateHang(*_args, **_kwargs):
            time.sleep(30)
            self.fail("Would hang forever.")

        self.conn.return_value.__enter__.side_effect = simulateHang

        # Verify that we fail, with expected timeout error.
        with self.assertRaises(timeout_util.TimeoutError):
            gob_util.FetchUrl("", "")

    def testHtmlParser(self):
        """Verify that GOB error message is parsed properly."""
        html_data = """
<!DOCTYPE html>
 <html lang=en>
 <meta charset=utf-8>
 <meta name=viewport>
 <title>Error 403 (Forbidden)!!1</title>
 <style>"*{margin:0;padding:0}"</style>
 <div id="af-error-container">
 <a href=//www.google.com><span id=logo aria-label=Google></span></a>

 <p>Error <b>403.</b><br><ins>That's an error.<p>Too bad...</ins>
 </div>
 <div id="come other stuff">
    some other stuff
 </div>
<html>"""
        expected_parsed_data = """Error 403.
That's an error.

Too bad..."""
        ep = gob_util.ErrorParser()
        ep.feed(html_data)
        ep.close()
        self.assertEqual(expected_parsed_data, ep.ParsedDiv())

    def testCreateChange(self):
        body = json.dumps({"change_num": 123456}).encode()
        xss_protection_prefix = b")]}'\n"
        body = xss_protection_prefix + body
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body=body, status=200
        )
        change_json = gob_util.CreateChange(
            "some.git.url", "project", "branch", "subject", True
        )
        self.assertEqual(change_json["change_num"], 123456)

        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body=body, status=201
        )
        change_json = gob_util.CreateChange(
            "some.git.url", "project", "branch", "subject", True
        )
        self.assertEqual(change_json["change_num"], 123456)

    def testChangeEdit(self):
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body={}, status=204
        )
        gob_util.ChangeEdit(
            "some.git.url", 123456, "some/file/path", "some file contents"
        )

    def testPublishChangeEdit(self):
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body={}, status=204
        )
        gob_util.PublishChangeEdit("some.git.url", 123456)

    def testGetFileContents(self):
        expected_contents = "some file contents"
        body = base64.b64encode(expected_contents.encode())
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body=body, status=200
        )
        contents = gob_util.GetFileContentsOnHead(
            "some.git.url", "some/file/path"
        )
        self.assertEqual(contents, expected_contents)
        contents = gob_util.GetFileContents("some.git.url", "some/file/path")
        self.assertEqual(contents, expected_contents)

    def testGetFileContentsFromGerrit(self):
        """Test for GetFileContentsFromGerrit()"""

        expected_contents = "some file contents"
        body = base64.b64encode(expected_contents.encode())
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body=body, status=200
        )
        contents = gob_util.GetFileContentsFromGerrit(
            "some.git.url", "100000", "some/file/path"
        )
        self.assertEqual(contents, expected_contents)

    def testGetChangeMergeable(self):
        """Test for GetChangeMergeable()"""

        mergeable_info = {"mergeable": True}
        body = json.dumps(mergeable_info).encode()
        xss_protection_prefix = b")]}'\n"
        body = xss_protection_prefix + body
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body=body, status=200
        )
        result = gob_util.GetChangeMergeable("some.git.url", "100000")
        self.assertEqual(result, mergeable_info)

    def testRebase(self):
        """Test for Rebase()"""

        change_info = {}
        body = json.dumps(change_info).encode()
        xss_protection_prefix = b")]}'\n"
        body = xss_protection_prefix + body
        self.conn.return_value.__enter__.return_value = FakeHTTPResponse(
            body=body, status=200
        )
        result = gob_util.Rebase("some.git.url", "100000")
        self.assertEqual(result, change_info)


class GetCookieTests(cros_test_lib.TestCase):
    """Unittests for GetCookies()"""

    def testSimple(self):
        with tempfile.NamedTemporaryFile(mode="w+") as f:
            f.write(".googlesource.com\tTRUE\t/f\tTRUE\t2147483647\to\tfoo=bar")
            f.flush()
            cookies = gob_util.GetCookies(
                "foo.googlesource.com", "/foo", [f.name]
            )
            self.assertEqual(cookies, {"o": "foo=bar"})
            cookies = gob_util.GetCookies("google.com", "/foo", [f.name])
            self.assertEqual(cookies, {})
            cookies = gob_util.GetCookies("foo.googlesource.com", "/", [f.name])
            self.assertEqual(cookies, {})


@cros_test_lib.pytestmark_network_test
class NetworkGobTest(cros_test_lib.TestCase):
    """Unittests that talk to real Gerrit."""

    def test200(self):
        """Test successful loading of change."""
        gob_util.FetchUrlJson(
            config_lib.GetSiteParams().EXTERNAL_GOB_HOST,
            "changes/227254/detail",
        )

    def test404(self):
        gob_util.FetchUrlJson(
            config_lib.GetSiteParams().EXTERNAL_GOB_HOST, "foo/bar/baz"
        )

    def test404Exception(self):
        with self.assertRaises(gob_util.GOBError) as ex:
            gob_util.FetchUrlJson(
                config_lib.GetSiteParams().EXTERNAL_GOB_HOST,
                "foo/bar/baz",
                ignore_404=False,
            )
        self.assertEqual(ex.exception.http_status, 404)
