# encoding: utf-8
"""Tests for IPython.utils.text"""

# -----------------------------------------------------------------------------
#  Copyright (C) 2011  The IPython Development Team
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------

import os
import sys
import math
import random

from pathlib import Path

import pytest

from IPython.utils import text

# -----------------------------------------------------------------------------
# Globals
# -----------------------------------------------------------------------------


def eval_formatter_list_comprehension_check(f):
    ns = dict(n=12)
    s = f.format("{[n//i for i in range(1,8)]}", **ns)
    assert s == "[12, 6, 4, 3, 2, 2, 1]"


def eval_formatter_check(f):
    ns = dict(n=12, pi=math.pi, stuff="hello there", os=os, u="café", b="café")
    s = f.format("{n} {n//4} {stuff.split()[0]}", **ns)
    assert s == "12 3 hello"
    s = f.format(" ".join(["{n//%i}" % i for i in range(1, 8)]), **ns)
    assert s == "12 6 4 3 2 2 1"
    s = f.format("{list(n//i for i in range(1,8))}", **ns)
    assert s == "[12, 6, 4, 3, 2, 2, 1]"
    s = f.format("{stuff!s}", **ns)
    assert s == ns["stuff"]
    s = f.format("{stuff!r}", **ns)
    assert s == repr(ns["stuff"])

    # Check with unicode:
    s = f.format("{u}", **ns)
    assert s == ns["u"]
    # This decodes in a platform dependent manner, but it shouldn't error out
    s = f.format("{b}", **ns)

    pytest.raises(NameError, f.format, "{dne}", **ns)


def eval_formatter_slicing_check(f):
    ns = dict(n=12, pi=math.pi, stuff="hello there", os=os)
    s = f.format(" {stuff.split()[:]} ", **ns)
    assert s == " ['hello', 'there'] "
    s = f.format(" {stuff.split()[::-1]} ", **ns)
    assert s == " ['there', 'hello'] "
    s = f.format("{stuff[::2]}", **ns)
    assert s == ns["stuff"][::2]

    pytest.raises(SyntaxError, f.format, "{n:x}", **ns)


def eval_formatter_no_slicing_check(f):
    ns = dict(n=12, pi=math.pi, stuff="hello there", os=os)

    s = f.format("{n:x} {pi**2:+f}", **ns)
    assert s == "c +9.869604"

    s = f.format("{stuff[slice(1,4)]}", **ns)
    assert s == "ell"

    s = f.format("{a[:]}", a=[1, 2])
    assert s == "[1, 2]"


def test_eval_formatter():
    f = text.EvalFormatter()
    eval_formatter_check(f)
    eval_formatter_no_slicing_check(f)
    if sys.version_info < (3, 14):
        eval_formatter_list_comprehension_check(f)


def test_full_eval_formatter():
    f = text.FullEvalFormatter()
    eval_formatter_check(f)
    eval_formatter_slicing_check(f)
    eval_formatter_list_comprehension_check(f)


def test_dollar_formatter():
    f = text.DollarFormatter()
    eval_formatter_check(f)
    eval_formatter_slicing_check(f)

    ns = dict(n=12, pi=math.pi, stuff="hello there", os=os)
    s = f.format("$n", **ns)
    assert s == "12"
    s = f.format("$n.real", **ns)
    assert s == "12"
    s = f.format("$n/{stuff[:5]}", **ns)
    assert s == "12/hello"
    s = f.format("$n $$HOME", **ns)
    assert s == "12 $HOME"
    s = f.format("${foo}", foo="HOME")
    assert s == "$HOME"


def test_strip_email():
    src = """\
        >> >>> def f(x):
        >> ...   return x+1
        >> ...
        >> >>> zz = f(2.5)"""
    cln = """\
>>> def f(x):
...   return x+1
...
>>> zz = f(2.5)"""
    assert text.strip_email_quotes(src) == cln


def test_strip_email2():
    src = "> > > list()"
    cln = "list()"
    assert text.strip_email_quotes(src) == cln


def test_LSString():
    lss = text.LSString("abc\ndef")
    assert lss.l == ["abc", "def"]
    assert lss.s == "abc def"
    lss = text.LSString(os.getcwd())
    assert isinstance(lss.p[0], Path)


def test_SList():
    sl = text.SList(["a 11", "b 1", "a 2"])
    assert sl.n == "a 11\nb 1\na 2"
    assert sl.s == "a 11 b 1 a 2"
    assert sl.grep(lambda x: x.startswith("a")) == text.SList(["a 11", "a 2"])
    assert sl.fields(0) == text.SList(["a", "b", "a"])
    assert sl.sort(field=1, nums=True) == text.SList(["b 1", "a 2", "a 11"])
