from datetime import datetime
from lambda_fn import check_beanstalk_health, monitor_beanstalk_app
from lambda_fn import FAILED, NED, SUCCESS
import boto3
import mock

cw = boto3.client('cloudwatch')
app = 'MyEBApp'
threshold = 0.75
empty = []
bad_threshold = [
    {'Sum': 1, 'Timestamp': 1},
    {'Sum': 1, 'Timestamp': 2},
    {'Sum': 0, 'Timestamp': 3},
    {'Sum': 1, 'Timestamp': 4}
]
bad_consecutive = [
    {'Sum': 0, 'Timestamp': 1},
    {'Sum': 0, 'Timestamp': 2},
    {'Sum': 1, 'Timestamp': 3},
    {'Sum': 1, 'Timestamp': 4}
]

good = [
    {'Sum': 1, 'Timestamp': 1},
    {'Sum': 0, 'Timestamp': 2},
    {'Sum': 0, 'Timestamp': 3},
    {'Sum': 0, 'Timestamp': 4}
]

@mock.patch('lambda_fn.get_cloudwatch_metrics', return_value=empty)
def test_check_beanstalk_no_data(mock_fn):
    result = check_beanstalk_health(cw, app, datetime.now(), threshold)

    assert result == NED
    assert mock_fn.call_count == 1

@mock.patch('lambda_fn.get_cloudwatch_metrics', return_value=bad_threshold)
def test_check_beanstalk_failure_threshold(mock_fn):
    result = check_beanstalk_health(cw, app, datetime.now(), threshold)

    assert result == FAILED
    assert mock_fn.call_count == 1

@mock.patch('lambda_fn.get_cloudwatch_metrics', return_value=bad_consecutive)
def test_check_beanstalk_failure_consecutive(mock_fn):
    result = check_beanstalk_health(cw, app, datetime.now(), threshold)

    assert result == FAILED
    assert mock_fn.call_count == 1

@mock.patch('lambda_fn.get_cloudwatch_metrics', return_value=good)
def test_check_beanstalk_success(mock_fn):
    result = check_beanstalk_health(cw, app, datetime.now(), threshold)

    assert result == SUCCESS
    assert mock_fn.call_count == 1

@mock.patch('lambda_fn.PERIOD_S', returns=1)
@mock.patch('lambda_fn.check_beanstalk_health', return_value=SUCCESS)
def test_monitor_beanstalk_app_success(mock_fn, mock_val):
    result = monitor_beanstalk_app(app, datetime.now(), 300, threshold)

    assert result == SUCCESS
    assert mock_fn.call_count == 1

@mock.patch('lambda_fn.check_beanstalk_health', return_value=FAILED)
def test_monitor_beanstalk_app_failure(mock_fn):
    result = monitor_beanstalk_app(app, datetime.now(), 300, threshold)

    assert result == FAILED
    assert mock_fn.call_count == 1

@mock.patch('lambda_fn.PERIOD_S', returns=1)
@mock.patch('lambda_fn.check_beanstalk_health', side_effect=[NED, SUCCESS])
def test_monitor_beanstalk_app_ned(mock_fn, mock_val):
    result = monitor_beanstalk_app(app, datetime.now(), 300, threshold)

    assert result == SUCCESS
    assert mock_fn.call_count == 2
