# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import sys
import unittest

from libcloud.utils.py3 import httplib
from libcloud.common.gandi_live import (
    GandiLiveBaseError,
    JsonParseError,
    InvalidRequestError,
)
from libcloud.dns.types import (
    RecordType,
    RecordError,
    ZoneDoesNotExistError,
    RecordDoesNotExistError,
    ZoneAlreadyExistsError,
    RecordAlreadyExistsError,
)
from libcloud.dns.drivers.gandi_live import GandiLiveDNSDriver
from libcloud.dns.base import Zone, Record
from libcloud.test.file_fixtures import DNSFileFixtures
from libcloud.test.secrets import DNS_GANDI_LIVE
from libcloud.test.common.test_gandi_live import BaseGandiLiveMockHttp


class GandiLiveTests(unittest.TestCase):
    def setUp(self):
        GandiLiveDNSDriver.connectionCls.conn_class = GandiLiveMockHttp
        GandiLiveMockHttp.type = None
        self.driver = GandiLiveDNSDriver(*DNS_GANDI_LIVE)
        self.test_zone = Zone(
            id="example.com",
            type="master",
            ttl=None,
            domain="example.com",
            extra={"zone_uuid": "a53re"},
            driver=self,
        )
        self.test_bad_zone = Zone(
            id="badexample.com",
            type="master",
            ttl=None,
            domain="badexample.com",
            extra={"zone_uuid": "a53rf"},
            driver=self,
        )
        self.test_record = Record(
            id="A:bob",
            type=RecordType.A,
            name="bob",
            zone=self.test_zone,
            data="127.0.0.1",
            driver=self,
            extra={},
        )
        self.test_bad_record = Record(
            id="A:jane",
            type=RecordType.A,
            name="jane",
            zone=self.test_bad_zone,
            data="127.0.0.1",
            driver=self,
            extra={},
        )

    def test_list_zones(self):
        zones = self.driver.list_zones()
        self.assertEqual(len(zones), 2)
        zone = zones[0]
        self.assertEqual(zone.id, "example.com")
        self.assertEqual(zone.type, "master")
        self.assertEqual(zone.domain, "example.com")
        self.assertIsNone(zone.ttl)
        zone = zones[1]
        self.assertEqual(zone.id, "example.net")
        self.assertEqual(zone.type, "master")
        self.assertEqual(zone.domain, "example.net")
        self.assertIsNone(zone.ttl)

    def test_create_zone(self):
        zone = self.driver.create_zone("example.org", extra={"name": "Example"})
        self.assertEqual(zone.id, "example.org")
        self.assertEqual(zone.domain, "example.org")
        self.assertEqual(zone.extra["zone_uuid"], "54321")

    def test_create_zone_without_name(self):
        zone = self.driver.create_zone("example.org")
        self.assertEqual(zone.id, "example.org")
        self.assertEqual(zone.domain, "example.org")
        self.assertEqual(zone.extra["zone_uuid"], "54321")

    def test_get_zone(self):
        zone = self.driver.get_zone("example.com")
        self.assertEqual(zone.id, "example.com")
        self.assertEqual(zone.type, "master")
        self.assertEqual(zone.domain, "example.com")
        self.assertIsNone(zone.ttl)

    def test_list_records(self):
        records = self.driver.list_records(self.test_zone)
        self.assertEqual(len(records), 3)
        record = records[0]
        self.assertEqual(record.id, "A:@")
        self.assertEqual(record.name, "@")
        self.assertEqual(record.type, RecordType.A)
        self.assertEqual(record.data, "127.0.0.1")
        record = records[1]
        self.assertEqual(record.id, "CNAME:www")
        self.assertEqual(record.name, "www")
        self.assertEqual(record.type, RecordType.CNAME)
        self.assertEqual(record.data, "bob.example.com.")
        record = records[2]
        self.assertEqual(record.id, "A:bob")
        self.assertEqual(record.name, "bob")
        self.assertEqual(record.type, RecordType.A)
        self.assertEqual(record.data, "127.0.1.1")

    def test_get_record(self):
        record = self.driver.get_record(self.test_zone.id, "A:bob")
        self.assertEqual(record.id, "A:bob")
        self.assertEqual(record.name, "bob")
        self.assertEqual(record.type, RecordType.A)
        self.assertEqual(record.data, "127.0.1.1")

    def test_create_record(self):
        record = self.driver.create_record(
            "alice", self.test_zone, "AAAA", "::1", extra={"ttl": 400}
        )
        self.assertEqual(record.id, "AAAA:alice")
        self.assertEqual(record.name, "alice")
        self.assertEqual(record.type, RecordType.AAAA)
        self.assertEqual(record.data, "::1")

    def test_create_record_doesnt_throw_if_ttl_is_not_provided(self):
        record = self.driver.create_record("alice", self.test_zone, "AAAA", "::1")
        self.assertEqual(record.id, "AAAA:alice")
        self.assertEqual(record.name, "alice")
        self.assertEqual(record.type, RecordType.AAAA)
        self.assertEqual(record.data, "::1")

    def test_bad_record_validation(self):
        with self.assertRaises(RecordError) as ctx:
            self.driver.create_record(
                "alice", self.test_zone, "AAAA", "1" * 1025, extra={"ttl": 400}
            )
        self.assertTrue("Record data must be" in str(ctx.exception))
        with self.assertRaises(RecordError) as ctx:
            self.driver.create_record(
                "alice", self.test_zone, "AAAA", "::1", extra={"ttl": 10}
            )
        self.assertTrue("TTL must be at least" in str(ctx.exception))
        with self.assertRaises(RecordError) as ctx:
            self.driver.create_record(
                "alice", self.test_zone, "AAAA", "::1", extra={"ttl": 31 * 24 * 60 * 60}
            )
        self.assertTrue("TTL must not exceed" in str(ctx.exception))

    def test_update_record(self):
        record = self.driver.update_record(
            self.test_record, "bob", RecordType.A, "192.168.0.2", {"ttl": 500}
        )
        self.assertEqual(record.id, "A:bob")
        self.assertEqual(record.name, "bob")
        self.assertEqual(record.type, RecordType.A)
        self.assertEqual(record.data, "192.168.0.2")

    def test_delete_record(self):
        success = self.driver.delete_record(self.test_record)
        self.assertTrue(success)

    def test_export_bind(self):
        bind_export = self.driver.export_zone_to_bind_format(self.test_zone)
        bind_lines = bind_export.decode("utf8").split("\n")
        self.assertEqual(bind_lines[0], "@ 10800 IN A 127.0.0.1")

    def test_bad_json_response(self):
        with self.assertRaises(JsonParseError):
            self.driver.get_zone("badexample.com")

    def test_no_record_found(self):
        with self.assertRaises(RecordDoesNotExistError):
            self.driver.get_record(self.test_zone.id, "A:none")

    def test_record_already_exists(self):
        with self.assertRaises(RecordAlreadyExistsError):
            self.driver.create_record(
                "bob", self.test_bad_zone, "A", "127.0.0.1", extra={"ttl": 400}
            )

    def test_no_zone_found(self):
        with self.assertRaises(ZoneDoesNotExistError):
            self.driver.get_zone("nosuchzone.com")

    def test_zone_already_exists(self):
        with self.assertRaises(ZoneAlreadyExistsError):
            self.driver.create_zone("badexample.com")

    # This is somewhat spurious - the driver should be preventing any invalid
    # request error from arising.
    def test_suberrors(self):
        with self.assertRaises(InvalidRequestError) as ctx:
            self.driver.update_record(
                self.test_bad_record, "jane", RecordType.A, "192.168.0.2", {"ttl": 500}
            )
        self.assertTrue("is not a foo" in str(ctx.exception))

    def test_other_error(self):
        with self.assertRaises(GandiLiveBaseError):
            self.driver.list_records(self.test_bad_zone)

    def test_mx_record(self):
        record = self.driver.get_record(self.test_zone.id, "MX:lists")
        self.assertEqual(record.extra["priority"], "10")
        self.assertTrue("_other_records" in record.extra)
        other_record = record.extra["_other_records"][0]
        self.assertEqual(other_record["extra"]["priority"], "20")

    def test_ex_create_multivalue_record(self):
        records = self.driver.ex_create_multi_value_record(
            "alice", self.test_zone, "AAAA", ["::1", "::2"], extra={"ttl": 400}
        )
        self.assertEqual(records[0].id, "AAAA:alice")
        self.assertEqual(records[0].name, "alice")
        self.assertEqual(records[0].type, RecordType.AAAA)
        self.assertEqual(records[0].data, "::1")
        self.assertEqual(records[1].id, "AAAA:alice")
        self.assertEqual(records[1].name, "alice")
        self.assertEqual(records[1].type, RecordType.AAAA)
        self.assertEqual(records[1].data, "::2")

    def test_update_multivalue_record(self):
        record = self.driver.get_record(self.test_zone.id, "MX:lists")
        updated = self.driver.update_record(
            record, None, None, "mail1", {"ttl": 400, "priority": 10}
        )
        self.assertEqual(updated.extra["priority"], "10")
        self.assertEqual(updated.data, "mail1")
        self.assertTrue("_other_records" in record.extra)
        other_record = record.extra["_other_records"][0]
        self.assertEqual(other_record["extra"]["priority"], "20")

    def test_ex_update_gandi_zone_name(self):
        updated = self.driver.ex_update_gandi_zone_name("111111", "Foo")
        self.assertTrue(updated)

    def test_ex_delete_gandi_zone(self):
        deleted = self.driver.ex_delete_gandi_zone("111111")
        self.assertTrue(deleted)


class GandiLiveMockHttp(BaseGandiLiveMockHttp):
    fixtures = DNSFileFixtures("gandi_live")

    def _json_api_v5_domains_get(self, method, url, body, headers):
        body = self.fixtures.load("list_zones.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_example_com_get(self, method, url, body, headers):
        body = self.fixtures.load("get_zone.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_badexample_com_get(self, method, url, body, headers):
        body = self.fixtures.load("get_bad_zone.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_nosuchzone_com_get(self, method, url, body, headers):
        body = self.fixtures.load("get_nonexistent_zone.json")
        return (httplib.NOT_FOUND, body, {}, httplib.responses[httplib.NOT_FOUND])

    def _json_api_v5_zones_post(self, method, url, body, headers):
        input = json.loads(body)
        if "badexample" in input["name"]:
            body = self.fixtures.load("create_bad_zone.json")
            return (httplib.CONFLICT, body, {}, httplib.responses[httplib.CONFLICT])
        else:
            body = self.fixtures.load("create_zone.json")
            return (
                httplib.OK,
                body,
                {"Location": "/zones/54321"},
                httplib.responses[httplib.OK],
            )

    def _json_api_v5_zones_111111_patch(self, method, url, body, headers):
        body = self.fixtures.load("update_gandi_zone.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_zones_111111_delete(self, method, url, body, headers):
        return (httplib.NO_CONTENT, "", {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_example_org_patch(self, method, url, body, headers):
        body = self.fixtures.load("create_domain.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_example_com_records_get(self, method, url, body, headers):
        body = self.fixtures.load("list_records.json")
        resp_headers = {}
        if (
            headers is not None
            and "Accept" in headers
            and headers["Accept"] == "text/plain"
        ):
            body = self.fixtures.load("list_records_bind.txt")
            resp_headers["Content-Type"] = "text/plain"
        return (httplib.OK, body, resp_headers, httplib.responses[httplib.OK])

    def _json_api_v5_domains_example_com_records_bob_A_get(
        self, method, url, body, headers
    ):
        body = self.fixtures.load("get_record.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_example_com_records_none_A_get(
        self, method, url, body, headers
    ):
        body = self.fixtures.load("get_nonexistent_record.json")
        return (httplib.NOT_FOUND, body, {}, httplib.responses[httplib.NOT_FOUND])

    def _json_api_v5_domains_example_com_records_lists_MX_get(
        self, method, url, body, headers
    ):
        body = self.fixtures.load("get_mx_record.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_example_com_records_lists_MX_put(
        self, method, url, body, headers
    ):
        body = self.fixtures.load("update_mx_record.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_example_com_records_post(self, method, url, body, headers):
        body = self.fixtures.load("create_record.json")
        return (
            httplib.OK,
            body,
            {"Location": "/zones/12345/records/alice/AAAA"},
            httplib.responses[httplib.OK],
        )

    def _json_api_v5_domains_badexample_com_records_post(
        self, method, url, body, headers
    ):
        body = self.fixtures.load("create_existing_record.json")
        return (httplib.CONFLICT, body, {}, httplib.responses[httplib.CONFLICT])

    def _json_api_v5_domains_badexample_com_records_get(
        self, method, url, body, headers
    ):
        return (
            httplib.INTERNAL_SERVER_ERROR,
            body,
            {},
            httplib.responses[httplib.INTERNAL_SERVER_ERROR],
        )

    def _json_api_v5_domains_badexample_com_records_jane_A_put(
        self, method, url, body, headers
    ):
        body = self.fixtures.load("update_bad_record.json")
        return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.BAD_REQUEST])

    def _json_api_v5_domains_example_com_records_bob_A_put(
        self, method, url, body, headers
    ):
        body = self.fixtures.load("update_record.json")
        return (httplib.OK, body, {}, httplib.responses[httplib.OK])

    def _json_api_v5_domains_example_com_records_bob_A_delete(
        self, method, url, body, headers
    ):
        return (httplib.NO_CONTENT, "", {}, httplib.responses[httplib.OK])


if __name__ == "__main__":
    sys.exit(unittest.main())
