import numpy as np
from pytest import fixture, mark, skip
from unittest.mock import patch
from pathlib import Path

from beyond.config import config
from beyond.dates.eop import Eop
from beyond.frames.stations import create_station
from beyond.io.tle import Tle
from beyond.propagators.keplernum import KeplerNum
from beyond.dates import Date, timedelta
from beyond.env.solarsystem import get_body


np.set_printoptions(linewidth=200)


@fixture(autouse=True, scope="session")
def config_override():
    """Create a dummy config dict containing basic data
    """

    config.update({
        "eop": {
            "missing_policy": "pass",
        }
    })


@fixture
def common_env():
    with patch('beyond.dates.date.EopDb.get') as m:
        m.return_value = Eop(
            x=-0.00951054166666622, y=0.31093590624999734, dpsi=-94.19544791666682,
            deps=-10.295645833333051, dy=-0.10067361111115315, dx=-0.06829513888889051,
            lod=1.6242802083331438, ut1_utc=0.01756018472222477, tai_utc=36.0
        )
        yield


@fixture
def station(common_env):
    return create_station('Toulouse', (43.604482, 1.443962, 172.))


@fixture
def iss_tle(common_env):
    return Tle("""ISS (ZARYA)
1 25544U 98067A   18124.55610684  .00001524  00000-0  30197-4 0  9997
2 25544  51.6421 236.2139 0003381  47.8509  47.6767 15.54198229111731""")


@fixture
def molniya_tle(common_env):
    return Tle("""MOLNIYA 1-90
1 24960U 97054A   18123.22759647  .00000163  00000-0  24467-3 0  9999
2 24960  62.6812 182.7824 6470982 294.8616  12.8538  3.18684355160009""")


@fixture(params=["tle", "ephem"])
def orbit(request, iss_tle):

    orb = iss_tle.orbit()

    if request.param == "tle":
        return orb
    elif request.param == "ephem":
        start = Date(2018, 4, 5, 16, 50)
        stop = timedelta(hours=6)
        step = timedelta(seconds=15)

        return orb.ephem(start=start, stop=stop, step=step)
    elif request.param == "kepler":
        orb.propagator = KeplerNum(
            timedelta(seconds=60),
            get_body('Earth')
        )
        return orb


@fixture(params=["tle", "ephem"])
def molniya(request, molniya_tle):

    orb = molniya_tle.orbit()

    if request.param == "tle":
        return orb
    elif request.param == "ephem":
        start = Date(2018, 4, 5, 16, 50)
        stop = timedelta(hours=15)
        step = timedelta(minutes=1)

        return orb.ephem(start=start, stop=stop, step=step)


@fixture
def jplfiles():
    config['env'] = {
        'jpl': [
            str(Path(__file__).parent / "data" / "jpl" / "de403_2000-2020.bsp"),
            str(Path(__file__).parent / "data" / "jpl" / "pck00010.tpc"),
            str(Path(__file__).parent / "data" / "jpl" / "gm_de431.tpc"),
        ]
    }


def _skip_if_no_mpl():
    """Specific for dynamically skipping the test if matplotlib is not present
    as it is not a dependency of the library, but merely a convenience
    """
    try:
        import matplotlib.pyplot as plt
    except ImportError:
        return True
    else:
        return False


def pytest_configure(config):
    """Declare the skip_if_no_mpl marker in pytest's '--markers' helper option
    This has no actual effect on the tests
    """
    config.addinivalue_line(
        "markers", "skip_if_no_mpl: skip if matplotlib is not installed"
    )


def pytest_runtest_setup(item):
    """This function is called for each test case.
    It looks if the test case has the skip_if_no_mpl decorator. If so, skip the test case
    """
    if _skip_if_no_mpl() and list(item.iter_markers(name="skip_if_no_mpl")):
        skip("matplotlib not installed")

[((400, 434), 'numpy.set_printoptions', 'np.set_printoptions', ([], {'linewidth': '(200)'}), '(linewidth=200)\n', (419, 434), True, 'import numpy as np\n'), ((438, 476), 'pytest.fixture', 'fixture', ([], {'autouse': '(True)', 'scope': '"""session"""'}), "(autouse=True, scope='session')\n", (445, 476), False, 'from pytest import fixture, mark, skip\n'), ((1573, 1605), 'pytest.fixture', 'fixture', ([], {'params': "['tle', 'ephem']"}), "(params=['tle', 'ephem'])\n", (1580, 1605), False, 'from pytest import fixture, mark, skip\n'), ((2090, 2122), 'pytest.fixture', 'fixture', ([], {'params': "['tle', 'ephem']"}), "(params=['tle', 'ephem'])\n", (2097, 2122), False, 'from pytest import fixture, mark, skip\n'), ((569, 619), 'beyond.config.config.update', 'config.update', (["{'eop': {'missing_policy': 'pass'}}"], {}), "({'eop': {'missing_policy': 'pass'}})\n", (582, 619), False, 'from beyond.config import config\n'), ((1089, 1145), 'beyond.frames.stations.create_station', 'create_station', (['"""Toulouse"""', '(43.604482, 1.443962, 172.0)'], {}), "('Toulouse', (43.604482, 1.443962, 172.0))\n", (1103, 1145), False, 'from beyond.frames.stations import create_station\n'), ((1192, 1359), 'beyond.io.tle.Tle', 'Tle', (['"""ISS (ZARYA)\n1 25544U 98067A   18124.55610684  .00001524  00000-0  30197-4 0  9997\n2 25544  51.6421 236.2139 0003381  47.8509  47.6767 15.54198229111731"""'], {}), '("""ISS (ZARYA)\n1 25544U 98067A   18124.55610684  .00001524  00000-0  30197-4 0  9997\n2 25544  51.6421 236.2139 0003381  47.8509  47.6767 15.54198229111731"""\n    )\n', (1195, 1359), False, 'from beyond.io.tle import Tle\n'), ((1406, 1574), 'beyond.io.tle.Tle', 'Tle', (['"""MOLNIYA 1-90\n1 24960U 97054A   18123.22759647  .00000163  00000-0  24467-3 0  9999\n2 24960  62.6812 182.7824 6470982 294.8616  12.8538  3.18684355160009"""'], {}), '("""MOLNIYA 1-90\n1 24960U 97054A   18123.22759647  .00000163  00000-0  24467-3 0  9999\n2 24960  62.6812 182.7824 6470982 294.8616  12.8538  3.18684355160009"""\n    )\n', (1409, 1574), False, 'from beyond.io.tle import Tle\n'), ((3232, 3325), 'beyond.config.config.addinivalue_line', 'config.addinivalue_line', (['"""markers"""', '"""skip_if_no_mpl: skip if matplotlib is not installed"""'], {}), "('markers',\n    'skip_if_no_mpl: skip if matplotlib is not installed')\n", (3255, 3325), False, 'from beyond.config import config\n'), ((695, 731), 'unittest.mock.patch', 'patch', (['"""beyond.dates.date.EopDb.get"""'], {}), "('beyond.dates.date.EopDb.get')\n", (700, 731), False, 'from unittest.mock import patch\n'), ((763, 995), 'beyond.dates.eop.Eop', 'Eop', ([], {'x': '(-0.00951054166666622)', 'y': '(0.31093590624999734)', 'dpsi': '(-94.19544791666682)', 'deps': '(-10.295645833333051)', 'dy': '(-0.10067361111115315)', 'dx': '(-0.06829513888889051)', 'lod': '(1.6242802083331438)', 'ut1_utc': '(0.01756018472222477)', 'tai_utc': '(36.0)'}), '(x=-0.00951054166666622, y=0.31093590624999734, dpsi=-94.19544791666682,\n    deps=-10.295645833333051, dy=-0.10067361111115315, dx=-\n    0.06829513888889051, lod=1.6242802083331438, ut1_utc=\n    0.01756018472222477, tai_utc=36.0)\n', (766, 995), False, 'from beyond.dates.eop import Eop\n'), ((3604, 3636), 'pytest.skip', 'skip', (['"""matplotlib not installed"""'], {}), "('matplotlib not installed')\n", (3608, 3636), False, 'from pytest import fixture, mark, skip\n'), ((1764, 1788), 'beyond.dates.Date', 'Date', (['(2018)', '(4)', '(5)', '(16)', '(50)'], {}), '(2018, 4, 5, 16, 50)\n', (1768, 1788), False, 'from beyond.dates import Date, timedelta\n'), ((1804, 1822), 'beyond.dates.timedelta', 'timedelta', ([], {'hours': '(6)'}), '(hours=6)\n', (1813, 1822), False, 'from beyond.dates import Date, timedelta\n'), ((1838, 1859), 'beyond.dates.timedelta', 'timedelta', ([], {'seconds': '(15)'}), '(seconds=15)\n', (1847, 1859), False, 'from beyond.dates import Date, timedelta\n'), ((2291, 2315), 'beyond.dates.Date', 'Date', (['(2018)', '(4)', '(5)', '(16)', '(50)'], {}), '(2018, 4, 5, 16, 50)\n', (2295, 2315), False, 'from beyond.dates import Date, timedelta\n'), ((2331, 2350), 'beyond.dates.timedelta', 'timedelta', ([], {'hours': '(15)'}), '(hours=15)\n', (2340, 2350), False, 'from beyond.dates import Date, timedelta\n'), ((2366, 2386), 'beyond.dates.timedelta', 'timedelta', ([], {'minutes': '(1)'}), '(minutes=1)\n', (2375, 2386), False, 'from beyond.dates import Date, timedelta\n'), ((2005, 2026), 'beyond.dates.timedelta', 'timedelta', ([], {'seconds': '(60)'}), '(seconds=60)\n', (2014, 2026), False, 'from beyond.dates import Date, timedelta\n'), ((2040, 2057), 'beyond.env.solarsystem.get_body', 'get_body', (['"""Earth"""'], {}), "('Earth')\n", (2048, 2057), False, 'from beyond.env.solarsystem import get_body\n'), ((2530, 2544), 'pathlib.Path', 'Path', (['__file__'], {}), '(__file__)\n', (2534, 2544), False, 'from pathlib import Path\n'), ((2611, 2625), 'pathlib.Path', 'Path', (['__file__'], {}), '(__file__)\n', (2615, 2625), False, 'from pathlib import Path\n'), ((2685, 2699), 'pathlib.Path', 'Path', (['__file__'], {}), '(__file__)\n', (2689, 2699), False, 'from pathlib import Path\n')]