from datetime import datetime as Datetime

import pytest
import requests

from delta_barth.api import requests as requests_
from delta_barth.api.common import LoginResponse


@pytest.mark.api_con_required
def test_get_sales_prognosis_data_Success(session):
    resp, status = session.login()
    # test without company ID
    assert status.code == 0
    date = Datetime(2022, 6, 1)
    resp, status = requests_.get_sales_prognosis_data(session, None, date)
    assert status.code == 0
    assert len(resp.daten) > 0
    date = Datetime(2030, 1, 1)
    resp, status = requests_.get_sales_prognosis_data(session, None, date)
    assert status.code == 0
    assert len(resp.daten) == 0
    # test with company ID
    assert status.code == 0
    date = Datetime(2022, 6, 1)
    company_id = 1024
    resp, status = requests_.get_sales_prognosis_data(session, company_id, date)
    assert status.code == 0
    assert len(resp.daten) > 0
    date = Datetime(2030, 1, 1)
    resp, status = requests_.get_sales_prognosis_data(session, company_id, date)
    assert status.code == 0
    assert len(resp.daten) == 0
    # test with non-existent company ID
    assert status.code == 0
    date = Datetime(2022, 6, 1)
    company_id = 1000024
    resp, status = requests_.get_sales_prognosis_data(session, company_id, date)
    # TODO check if this behaviour is still considered "successful"
    assert status.code == 0
    assert len(resp.daten) == 0
    # test without date
    company_id = 1024
    resp, status = requests_.get_sales_prognosis_data(session, company_id, None)
    assert status.code == 0
    assert len(resp.daten) > 0
    # test without filters
    resp, status = requests_.get_sales_prognosis_data(session, None, None)
    assert status.code == 0
    assert len(resp.daten) > 0
    # close connection
    resp, status = session.logout()
    assert status.code == 0


@pytest.mark.api_con_required
def test_get_sales_prognosis_data_FailLogin(session, mock_get):
    session.login()
    code = 500
    json = {
        "message": "ServerError",
        "code": "TestExternalServerError",
        "hints": "TestCase",
    }
    mock_get.return_value.status_code = code
    mock_get.return_value.json.return_value = json

    resp, status = requests_.get_sales_prognosis_data(session, None, None)
    assert resp is not None
    assert len(resp.daten) == 0
    assert status.code == 400
    assert status.api_server_error is not None
    assert status.api_server_error.status_code == code
    assert status.api_server_error.message == json["message"]
    assert status.api_server_error.code == json["code"]
    assert status.api_server_error.hints == json["hints"]


@pytest.mark.api_con_required
def test_get_sales_prognosis_data_FailApiServer(session, mock_get):
    code = 405
    json = {
        "message": "ServerError",
        "code": "TestExternalServerError",
        "hints": "TestCase",
    }
    mock_get.return_value.status_code = code
    mock_get.return_value.json.return_value = json

    resp, status = requests_.get_sales_prognosis_data(session, None, None)
    assert resp is not None
    assert len(resp.daten) == 0
    assert status.code == 400
    assert status.api_server_error is not None
    assert status.api_server_error.status_code == code
    assert status.api_server_error.message == json["message"]
    assert status.api_server_error.code == json["code"]
    assert status.api_server_error.hints == json["hints"]


def test_get_sales_prognosis_data_FailGetTimeout(session, mock_get):
    mock_get.side_effect = requests.exceptions.Timeout("Test timeout")

    def assert_login():
        return LoginResponse(token=""), requests_.STATUS_HANDLER.SUCCESS

    session.assert_login = assert_login

    resp, status = requests_.get_sales_prognosis_data(session, None, None)
    assert resp is not None
    assert len(resp.daten) == 0
    assert status.code == 1


def test_get_sales_prognosis_data_FailGetRequestException(session, mock_get):
    mock_get.side_effect = requests.exceptions.RequestException("Test not timeout")

    def assert_login():
        return LoginResponse(token=""), requests_.STATUS_HANDLER.SUCCESS

    session.assert_login = assert_login

    resp, status = requests_.get_sales_prognosis_data(session, None, None)
    assert resp is not None
    assert len(resp.daten) == 0
    assert status.code == 2
