# 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 os.path
import sys
import unittest

import libcloud.pricing

PRICING_FILE_PATH = os.path.join(os.path.dirname(__file__), "pricing_test.json")


class PricingTestCase(unittest.TestCase):
    def setUp(self):
        super(PricingTestCase, self).setUp()

        libcloud.pricing.PRICING_DATA = {"compute": {}, "storage": {}}

    def test_get_pricing_success(self):
        self.assertFalse("foo" in libcloud.pricing.PRICING_DATA["compute"])

        pricing = libcloud.pricing.get_pricing(
            driver_type="compute",
            driver_name="foo",
            pricing_file_path=PRICING_FILE_PATH,
        )
        self.assertEqual(pricing["1"], 1.0)
        self.assertEqual(pricing["2"], 2.0)

        self.assertEqual(libcloud.pricing.PRICING_DATA["compute"]["foo"]["1"], 1.0)
        self.assertEqual(libcloud.pricing.PRICING_DATA["compute"]["foo"]["2"], 2.0)

    def test_get_pricing_invalid_file_path(self):
        try:
            libcloud.pricing.get_pricing(
                driver_type="compute",
                driver_name="bar",
                pricing_file_path="inexistent.json",
            )
        except IOError:
            pass
        else:
            self.fail(
                "Invalid pricing file path provided, but an exception was not" " thrown"
            )

    def test_get_pricing_invalid_driver_type(self):
        try:
            libcloud.pricing.get_pricing(
                driver_type="invalid_type",
                driver_name="bar",
                pricing_file_path="inexistent.json",
            )
        except AttributeError:
            pass
        else:
            self.fail(
                "Invalid driver_type provided, but an exception was not" " thrown"
            )

    def test_get_pricing_not_in_cache(self):
        try:
            libcloud.pricing.get_pricing(
                driver_type="compute",
                driver_name="inexistent",
                pricing_file_path=PRICING_FILE_PATH,
            )
        except KeyError:
            pass
        else:
            self.fail("Invalid driver provided, but an exception was not" " thrown")

    def test_get_size_price(self):
        libcloud.pricing.PRICING_DATA["compute"]["foo"] = {2: 2, "3": 3}
        price1 = libcloud.pricing.get_size_price(
            driver_type="compute", driver_name="foo", size_id=2
        )
        price2 = libcloud.pricing.get_size_price(
            driver_type="compute", driver_name="foo", size_id="3"
        )
        self.assertEqual(price1, 2)
        self.assertEqual(price2, 3)

    def test_invalid_pricing_cache(self):
        libcloud.pricing.PRICING_DATA["compute"]["foo"] = {2: 2}
        self.assertTrue("foo" in libcloud.pricing.PRICING_DATA["compute"])

        libcloud.pricing.invalidate_pricing_cache()
        self.assertFalse("foo" in libcloud.pricing.PRICING_DATA["compute"])

    def test_invalid_module_pricing_cache(self):
        libcloud.pricing.PRICING_DATA["compute"]["foo"] = {1: 1}

        self.assertTrue("foo" in libcloud.pricing.PRICING_DATA["compute"])

        libcloud.pricing.invalidate_module_pricing_cache(
            driver_type="compute", driver_name="foo"
        )
        self.assertFalse("foo" in libcloud.pricing.PRICING_DATA["compute"])
        libcloud.pricing.invalidate_module_pricing_cache(
            driver_type="compute", driver_name="foo1"
        )

    def test_set_pricing(self):
        self.assertFalse("foo" in libcloud.pricing.PRICING_DATA["compute"])

        libcloud.pricing.set_pricing(
            driver_type="compute", driver_name="foo", pricing={"foo": 1}
        )
        self.assertTrue("foo" in libcloud.pricing.PRICING_DATA["compute"])

    def test_get_pricing_data_caching(self):
        # Ensure we only cache pricing data in memory for requested drivers
        self.assertEqual(libcloud.pricing.PRICING_DATA["compute"], {})
        self.assertEqual(libcloud.pricing.PRICING_DATA["storage"], {})

        pricing = libcloud.pricing.get_pricing(
            driver_type="compute",
            driver_name="foo",
            pricing_file_path=PRICING_FILE_PATH,
        )
        self.assertEqual(pricing["1"], 1.0)
        self.assertEqual(pricing["2"], 2.0)

        self.assertEqual(len(libcloud.pricing.PRICING_DATA["compute"]), 1)
        self.assertTrue("foo" in libcloud.pricing.PRICING_DATA["compute"])

        pricing = libcloud.pricing.get_pricing(
            driver_type="compute",
            driver_name="baz",
            pricing_file_path=PRICING_FILE_PATH,
        )
        self.assertEqual(pricing["1"], 5.0)
        self.assertEqual(pricing["2"], 6.0)

        self.assertEqual(len(libcloud.pricing.PRICING_DATA["compute"]), 2)
        self.assertTrue("foo" in libcloud.pricing.PRICING_DATA["compute"])
        self.assertTrue("baz" in libcloud.pricing.PRICING_DATA["compute"])

    def test_get_pricing_data_module_level_variable_is_true(self):
        # Ensure we only cache pricing data in memory for requested drivers
        self.assertEqual(libcloud.pricing.PRICING_DATA["compute"], {})
        self.assertEqual(libcloud.pricing.PRICING_DATA["storage"], {})

        libcloud.pricing.CACHE_ALL_PRICING_DATA = True

        pricing = libcloud.pricing.get_pricing(
            driver_type="compute",
            driver_name="foo",
            pricing_file_path=PRICING_FILE_PATH,
            cache_all=False,
        )
        self.assertEqual(pricing["1"], 1.0)
        self.assertEqual(pricing["2"], 2.0)

        self.assertEqual(len(libcloud.pricing.PRICING_DATA["compute"]), 3)
        self.assertTrue("foo" in libcloud.pricing.PRICING_DATA["compute"])
        self.assertTrue("bar" in libcloud.pricing.PRICING_DATA["compute"])
        self.assertTrue("baz" in libcloud.pricing.PRICING_DATA["compute"])

    def test_get_pricing_data_caching_cache_all(self):
        # Ensure we only cache pricing data in memory for requested drivers
        self.assertEqual(libcloud.pricing.PRICING_DATA["compute"], {})
        self.assertEqual(libcloud.pricing.PRICING_DATA["storage"], {})

        pricing = libcloud.pricing.get_pricing(
            driver_type="compute",
            driver_name="foo",
            pricing_file_path=PRICING_FILE_PATH,
            cache_all=True,
        )
        self.assertEqual(pricing["1"], 1.0)
        self.assertEqual(pricing["2"], 2.0)

        self.assertEqual(len(libcloud.pricing.PRICING_DATA["compute"]), 3)
        self.assertTrue("foo" in libcloud.pricing.PRICING_DATA["compute"])
        self.assertTrue("bar" in libcloud.pricing.PRICING_DATA["compute"])
        self.assertTrue("baz" in libcloud.pricing.PRICING_DATA["compute"])


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