# Copyright 2017 Google Inc.
#
# Licensed 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.

"""Unit and system tests for metricscaler.py"""

import os
import uuid

from google.cloud import bigtable
from google.cloud.bigtable import enums
from mock import Mock, patch

import pytest
from test_utils.retry import RetryInstanceState
from test_utils.retry import RetryResult

from metricscaler import get_cpu_load
from metricscaler import get_storage_utilization
from metricscaler import main
from metricscaler import scale_bigtable


PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"]
BIGTABLE_ZONE = os.environ["BIGTABLE_ZONE"]
SIZE_CHANGE_STEP = 3
INSTANCE_ID_FORMAT = "metric-scale-test-{}"
BIGTABLE_INSTANCE = INSTANCE_ID_FORMAT.format(str(uuid.uuid4())[:10])
BIGTABLE_DEV_INSTANCE = INSTANCE_ID_FORMAT.format(str(uuid.uuid4())[:10])


# System tests to verify API calls succeed


@patch("metricscaler.query")
def test_get_cpu_load(monitoring_v3_query):
    iter_mock = monitoring_v3_query.Query().select_resources().iter
    iter_mock.return_value = iter([Mock(points=[Mock(value=Mock(double_value=1.0))])])
    assert float(get_cpu_load(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE)) > 0.0


@patch("metricscaler.query")
def test_get_storage_utilization(monitoring_v3_query):
    iter_mock = monitoring_v3_query.Query().select_resources().iter
    iter_mock.return_value = iter([Mock(points=[Mock(value=Mock(double_value=1.0))])])
    assert float(get_storage_utilization(BIGTABLE_INSTANCE, BIGTABLE_INSTANCE)) > 0.0


@pytest.fixture()
def instance():
    cluster_id = BIGTABLE_INSTANCE

    client = bigtable.Client(project=PROJECT, admin=True)

    serve_nodes = 1
    storage_type = enums.StorageType.SSD
    production = enums.Instance.Type.PRODUCTION
    labels = {"prod-label": "prod-label"}
    instance = client.instance(
        BIGTABLE_INSTANCE, instance_type=production, labels=labels
    )

    if not instance.exists():
        cluster = instance.cluster(
            cluster_id,
            location_id=BIGTABLE_ZONE,
            serve_nodes=serve_nodes,
            default_storage_type=storage_type,
        )
        instance.create(clusters=[cluster])

        # Eventual consistency check
        retry_found = RetryResult(bool)
        retry_found(instance.exists)()

    yield

    instance.delete()