import numpy as np
import pytest

import pandas as pd
from pandas import Series, Timedelta, timedelta_range
import pandas._testing as tm


class TestSlicing:
    def test_slice_keeps_name(self):
        # GH4226
        dr = pd.timedelta_range("1d", "5d", freq="H", name="timebucket")
        assert dr[1:].name == dr.name

    def test_partial_slice(self):
        rng = timedelta_range("1 day 10:11:12", freq="h", periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["5 day":"6 day"]
        expected = s.iloc[86:134]
        tm.assert_series_equal(result, expected)

        result = s["5 day":]
        expected = s.iloc[86:]
        tm.assert_series_equal(result, expected)

        result = s[:"6 day"]
        expected = s.iloc[:134]
        tm.assert_series_equal(result, expected)

        result = s["6 days, 23:11:12"]
        assert result == s.iloc[133]

        msg = r"^Timedelta\('50 days 00:00:00'\)$"
        with pytest.raises(KeyError, match=msg):
            s["50 days"]

    def test_partial_slice_high_reso(self):

        # higher reso
        rng = timedelta_range("1 day 10:11:12", freq="us", periods=2000)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["1 day 10:11:12":]
        expected = s.iloc[0:]
        tm.assert_series_equal(result, expected)

        result = s["1 day 10:11:12.001":]
        expected = s.iloc[1000:]
        tm.assert_series_equal(result, expected)

        result = s["1 days, 10:11:12.001001"]
        assert result == s.iloc[1001]

    def test_slice_with_negative_step(self):
        ts = Series(np.arange(20), timedelta_range("0", periods=20, freq="H"))
        SLC = pd.IndexSlice

        def assert_slices_equivalent(l_slc, i_slc):
            tm.assert_series_equal(ts[l_slc], ts.iloc[i_slc])
            tm.assert_series_equal(ts.loc[l_slc], ts.iloc[i_slc])
            tm.assert_series_equal(ts.loc[l_slc], ts.iloc[i_slc])

        assert_slices_equivalent(SLC[Timedelta(hours=7) :: -1], SLC[7::-1])
        assert_slices_equivalent(SLC["7 hours"::-1], SLC[7::-1])

        assert_slices_equivalent(SLC[: Timedelta(hours=7) : -1], SLC[:6:-1])
        assert_slices_equivalent(SLC[:"7 hours":-1], SLC[:6:-1])

        assert_slices_equivalent(SLC["15 hours":"7 hours":-1], SLC[15:6:-1])
        assert_slices_equivalent(
            SLC[Timedelta(hours=15) : Timedelta(hours=7) : -1], SLC[15:6:-1]
        )
        assert_slices_equivalent(
            SLC["15 hours" : Timedelta(hours=7) : -1], SLC[15:6:-1]
        )
        assert_slices_equivalent(
            SLC[Timedelta(hours=15) : "7 hours" : -1], SLC[15:6:-1]
        )

        assert_slices_equivalent(SLC["7 hours":"15 hours":-1], SLC[:0])

    def test_slice_with_zero_step_raises(self):
        ts = Series(np.arange(20), timedelta_range("0", periods=20, freq="H"))
        with pytest.raises(ValueError, match="slice step cannot be zero"):
            ts[::0]
        with pytest.raises(ValueError, match="slice step cannot be zero"):
            ts.loc[::0]
        with pytest.raises(ValueError, match="slice step cannot be zero"):
            ts.loc[::0]
