# -*- coding: utf-8 -*-
"""\
Here are a collection of examples of how this module can be used.
See the README or the natsort homepage for more details.
"""
from __future__ import print_function, unicode_literals

from operator import itemgetter

import pytest
from natsort import (
    as_ascii,
    as_utf8,
    decoder,
    humansorted,
    index_humansorted,
    index_natsorted,
    index_realsorted,
    natsorted,
    ns,
    order_by_index,
    realsorted,
)
from natsort.compat.py23 import PY_VERSION


@pytest.fixture
def version_list():
    return ["1.9.9a", "1.11", "1.9.9b", "1.11.4", "1.10.1"]


@pytest.fixture
def float_list():
    return ["a50", "a51.", "a50.31", "a-50", "a50.4", "a5.034e1", "a50.300"]


@pytest.fixture
def fruit_list():
    return ["Apple", "corn", "Corn", "Banana", "apple", "banana"]


def test_decoder_returns_function_that_can_decode_bytes_but_return_non_bytes_as_is():
    func = decoder("latin1")
    str_obj = "bytes"
    int_obj = 14
    assert func(b"bytes") == str_obj
    assert func(int_obj) is int_obj  # returns as-is, same object ID
    if PY_VERSION >= 3:
        assert (
            func(str_obj) is str_obj
        )  # same object returned on Python3 b/c only bytes has decode
    else:
        assert func(str_obj) is not str_obj
        assert (
            func(str_obj) == str_obj
        )  # not same object on Python2 because str can decode


def test_as_ascii_converts_bytes_to_ascii():
    assert decoder("ascii")(b"bytes") == as_ascii(b"bytes")


def test_as_utf8_converts_bytes_to_utf8():
    assert decoder("utf8")(b"bytes") == as_utf8(b"bytes")


def test_realsorted_is_identical_to_natsorted_with_real_alg(float_list):
    assert realsorted(float_list) == natsorted(float_list, alg=ns.REAL)


@pytest.mark.usefixtures("with_locale_en_us")
def test_humansorted_is_identical_to_natsorted_with_locale_alg(fruit_list):
    assert humansorted(fruit_list) == natsorted(fruit_list, alg=ns.LOCALE)


def test_index_natsorted_returns_integer_list_of_sort_order_for_input_list():
    given = ["num3", "num5", "num2"]
    other = ["foo", "bar", "baz"]
    index = index_natsorted(given)
    assert index == [2, 0, 1]
    assert [given[i] for i in index] == ["num2", "num3", "num5"]
    assert [other[i] for i in index] == ["baz", "foo", "bar"]


def test_index_natsorted_reverse():
    given = ["num3", "num5", "num2"]
    assert index_natsorted(given, reverse=True) == index_natsorted(given)[::-1]


def test_index_natsorted_applies_key_function_before_sorting():
    given = [("a", "num3"), ("b", "num5"), ("c", "num2")]
    expected = [2, 0, 1]
    assert index_natsorted(given, key=itemgetter(1)) == expected


def test_index_realsorted_is_identical_to_index_natsorted_with_real_alg(float_list):
    assert index_realsorted(float_list) == index_natsorted(float_list, alg=ns.REAL)


@pytest.mark.usefixtures("with_locale_en_us")
def test_index_humansorted_is_identical_to_index_natsorted_with_locale_alg(fruit_list):
    assert index_humansorted(fruit_list) == index_natsorted(fruit_list, alg=ns.LOCALE)


def test_order_by_index_sorts_list_according_to_order_of_integer_list():
    given = ["num3", "num5", "num2"]
    index = [2, 0, 1]
    expected = [given[i] for i in index]
    assert expected == ["num2", "num3", "num5"]
    assert order_by_index(given, index) == expected


def test_order_by_index_returns_generator_with_iter_true():
    given = ["num3", "num5", "num2"]
    index = [2, 0, 1]
    assert order_by_index(given, index, True) != [given[i] for i in index]
    assert list(order_by_index(given, index, True)) == [given[i] for i in index]
