# Licensed under a 3-clause BSD style license - see LICENSE.rst

"""
This module tests some of the methods related to YAML serialization.

Requires `pyyaml <https://pyyaml.org/>`_ to be installed.
"""

from io import StringIO

import pytest
import numpy as np

from astropy.coordinates import SkyCoord, EarthLocation, Angle, Longitude, Latitude
from astropy import units as u
from astropy.time import Time
from astropy.table import QTable, SerializedColumn
from astropy.tests.helper import catch_warnings

try:
    from astropy.io.misc.yaml import load, load_all, dump
    HAS_YAML = True
except ImportError:
    HAS_YAML = False

pytestmark = pytest.mark.skipif('not HAS_YAML')


@pytest.mark.parametrize('c', [True, np.uint8(8), np.int16(4),
                               np.int32(1), np.int64(3), np.int64(2**63 - 1),
                               2.0, np.float64(),
                               3+4j, np.complex_(3 + 4j),
                               np.complex64(3 + 4j),
                               np.complex128(1. - 2**-52 + 1j * (1. - 2**-52))])
def test_numpy_types(c):
    cy = load(dump(c))
    assert c == cy


@pytest.mark.parametrize('c', [u.m, u.m / u.s, u.hPa, u.dimensionless_unscaled])
def test_unit(c):
    cy = load(dump(c))
    if isinstance(c, u.CompositeUnit):
        assert c == cy
    else:
        assert c is cy


@pytest.mark.parametrize('c', [u.Unit('bakers_dozen', 13*u.one),
                               u.def_unit('magic')])
def test_custom_unit(c):
    s = dump(c)
    with catch_warnings() as w:
        cy = load(s)
    assert len(w) == 1
    assert f"'{c!s}' did not parse" in str(w[0].message)
    assert isinstance(cy, u.UnrecognizedUnit)
    assert str(cy) == str(c)

    with u.add_enabled_units(c):
        with catch_warnings() as w2:
            cy2 = load(s)
        assert len(w2) == 0

        assert cy2 is c


@pytest.mark.parametrize('c', [Angle('1 2 3', unit='deg'),
                               Longitude('1 2 3', unit='deg'),
                               Latitude('1 2 3', unit='deg'),
                               [[1], [3]] * u.m,
                               np.array([[1, 2], [3, 4]], order='F'),
                               np.array([[1, 2], [3, 4]], order='C'),
                               np.array([1, 2, 3, 4])[::2]])
def test_ndarray_subclasses(c):
    cy = load(dump(c))

    assert np.all(c == cy)
    assert c.shape == cy.shape
    assert type(c) is type(cy)