import unittest
from unittest.mock import MagicMock, patch

import pytest

from app import app
from app.terraform.proxy import update_smart_proxy_instance
from app.terraform.proxy.meta import random_slug, next_subgroup, Proxy


class TestUpdateSmartProxyInstance(unittest.TestCase):
    def setUp(self):
        self.group_id = 1
        self.provider = 'test_provider'
        self.region = 'test_region'
        self.instance_id = 'test_instance_id'
        app.config['TESTING'] = True
        self.app = app.test_client()

    @patch('app.terraform.proxy.SmartProxy')
    @patch('app.terraform.proxy.db')
    def test_update_smart_proxy_instance_new(self, mock_db, mock_smart_proxy):
        # Configure the mocked SmartProxy query to return None
        mock_smart_proxy.query.filter.return_value.first.return_value = None

        # Call the function
        update_smart_proxy_instance(self.group_id, self.provider, self.region, self.instance_id)

        # Assert that a new SmartProxy instance was created and added to the session
        mock_smart_proxy.assert_called_once()
        mock_db.session.add.assert_called_once()

    @patch('app.terraform.proxy.SmartProxy')
    @patch('app.terraform.proxy.db')
    def test_update_smart_proxy_instance_existing(self, mock_db, mock_smart_proxy):
        # Configure the mocked SmartProxy query to return an existing instance
        mock_instance = MagicMock()
        mock_smart_proxy.query.filter.return_value.first.return_value = mock_instance

        # Call the function
        update_smart_proxy_instance(self.group_id, self.provider, self.region, self.instance_id)

        # Assert that the existing SmartProxy instance was updated
        self.assertEqual(mock_instance.instance_id, self.instance_id)


@pytest.fixture
def active_proxies():
    proxies = [MagicMock(spec=Proxy) for _ in range(5)]
    for proxy in proxies:
        proxy.deprecated = None
        proxy.destroyed = None
    return proxies


def test_random_slug():
    slug = random_slug("example.com")
    assert slug[:5] == "examp"
    assert len(slug) == 17


def test_next_subgroup():
    subgroup_count = {
        'provider1': {
            1: {
                1: 3
            },
            2: {
                1: 2,
                2: 5
            },
            3: {}
        }
    }
    assert next_subgroup(subgroup_count, 'provider1', 1, 3, 5) == 1
    assert next_subgroup(subgroup_count, 'provider1', 1, 5, 3) == 2
    assert next_subgroup(subgroup_count, 'provider1', 2, 3, 2) == 3
    assert next_subgroup(subgroup_count, 'provider1', 3, 3, 5) == 1
