"""API tests.
"""

import io
import os

import pytest

import rarfile

if rarfile._have_pathlib:
    from pathlib import Path

#
# test start
#

def test_bad_arc_mode_w():
    with pytest.raises(NotImplementedError):
        rarfile.RarFile('test/files/rar3-comment-plain.rar', 'w')

def test_bad_arc_mode_rb():
    with pytest.raises(NotImplementedError):
        rarfile.RarFile('test/files/rar3-comment-plain.rar', 'rb')

def test_bad_errs():
    with pytest.raises(ValueError):
        rarfile.RarFile('test/files/rar3-comment-plain.rar', 'r', errors='foo')

def test_bad_open_mode_w():
    rf = rarfile.RarFile('test/files/rar3-comment-plain.rar')
    with pytest.raises(NotImplementedError):
        rf.open('qwe', 'w')

def test_bad_open_psw():
    rf = rarfile.RarFile('test/files/rar3-comment-psw.rar')
    with pytest.raises(rarfile.PasswordRequired):
        rf.open('file1.txt')

def test_bad_filelike():
    with pytest.raises(ValueError):
        rarfile.is_rarfile(bytearray(10))

def test_open_psw_late_rar3():
    rf = rarfile.RarFile('test/files/rar3-comment-psw.rar')
    d1 = rf.open('file1.txt', 'r', 'password').read()
    d2 = rf.open('file1.txt', 'r', u'password').read()
    assert d1 == d2

def test_open_psw_late_rar5():
    rf = rarfile.RarFile('test/files/rar5-psw.rar')
    rf.open('stest1.txt', 'r', 'password').read()
    rf.open('stest1.txt', 'r', u'password').read()

if rarfile._have_pathlib:
    def test_open_pathlib_path():
        rf = rarfile.RarFile('test/files/rar5-psw.rar')
        rf.open(Path('stest1.txt'), 'r', 'password').read()

def test_read_psw_late_rar3():
    rf = rarfile.RarFile('test/files/rar3-comment-psw.rar')
    rf.read('file1.txt', 'password')
    rf.read('file1.txt', u'password')

def test_read_psw_late_rar5():
    rf = rarfile.RarFile('test/files/rar5-psw.rar')
    rf.read('stest1.txt', 'password')
    rf.read('stest1.txt', u'password')

def test_open_psw_late():
    rf = rarfile.RarFile('test/files/rar5-psw.rar')
    with pytest.raises(rarfile.BadRarFile):
        rf.read('stest1.txt', 'password222')

if rarfile._have_pathlib:
    def test_create_from_pathlib_path():
        # Make sure we can open both relative and absolute Paths
        rarfile.RarFile(Path('test/files/rar5-psw.rar'))
        rarfile.RarFile(Path('test/files/rar5-psw.rar').resolve())

def test_detection():
    assert rarfile.is_rarfile('test/files/ctime4.rar.exp') is False
    assert rarfile.is_rarfile('test/files/ctime4.rar') is True
    assert rarfile.is_rarfile('test/files/rar5-crc.rar') is True

    if rarfile._have_pathlib:
        assert rarfile.is_rarfile(Path('test/files/rar5-crc.rar')) is True


def test_signature_error():
    with pytest.raises(rarfile.BadRarFile):
        rarfile.RarFile('test/files/ctime4.rar.exp')

def test_signature_error_mem():
    data = io.BytesIO(b'x'*40)
    with pytest.raises(rarfile.BadRarFile):
        rarfile.RarFile(data)

def test_with():
    with rarfile.RarFile('test/files/rar5-crc.rar') as rf:
        data = rf.read('stest1.txt')
        with rf.open('stest1.txt') as f:
            dst = io.BytesIO()
            while 1:
                buf = f.read(7)
                if not buf:
                    break
                dst.write(buf)
            assert dst.getvalue() == data

def test_readline():
    def load_readline(rf, fn):
        with rf.open(fn) as f:
            tr = io.TextIOWrapper(io.BufferedReader(f))
            res = []
            while 1:
                ln = tr.readline()
                if not ln:
                    break
                res.append(ln)
        return res

    rf = rarfile.RarFile('test/files/seektest.rar')
    v1 = load_readline(rf, 'stest1.txt')
    v2 = load_readline(rf, 'stest2.txt')
    assert len(v1) == 512
    assert v1 == v2

def test_printdir(capsys):
    rf = rarfile.RarFile('test/files/seektest.rar')
    rf.printdir()
    res = capsys.readouterr()
    assert res.out == u'stest1.txt\nstest2.txt\n'

def test_testrar():
    rf = rarfile.RarFile('test/files/seektest.rar')
    rf.testrar()

def test_testrar_mem():
    arc = open('test/files/seektest.rar', 'rb').read()
    rf = rarfile.RarFile(io.BytesIO(arc))
    rf.testrar()

def test_extract(tmp_path):
    ex1 = tmp_path / "extract1"
    ex2 = tmp_path / "extract2"
    ex3 = tmp_path / "extract3"
    os.makedirs(str(ex1))
    os.makedirs(str(ex2))
    os.makedirs(str(ex3))
    rf = rarfile.RarFile('test/files/seektest.rar')

    rf.extractall(str(ex1))
    assert os.path.isfile(str(ex1 / 'stest1.txt')) is True
    assert os.path.isfile(str(ex1 / 'stest2.txt')) is True

    rf.extract('stest1.txt', str(ex2))
    assert os.path.isfile(str(ex2 / 'stest1.txt')) is True
    assert os.path.isfile(str(ex2 / 'stest2.txt')) is False

    inf = rf.getinfo('stest2.txt')
    rf.extract(inf, str(ex3))
    assert os.path.isfile(str(ex3 / 'stest1.txt')) is False
    assert os.path.isfile(str(ex3 / 'stest2.txt')) is True

    rf.extractall(str(ex2), ['stest1.txt'])
    assert os.path.isfile(str(ex2 / 'stest1.txt')) is True

    rf.extractall(str(ex3), [rf.getinfo('stest2.txt')])
    assert os.path.isfile(str(ex3 / 'stest2.txt')) is True

    if rarfile._have_pathlib:
        ex4 = tmp_path / "extract4"
        os.makedirs(str(ex4))
        rf.extractall(ex4)
        assert os.path.isfile(str(ex4 / 'stest1.txt')) is True
        assert os.path.isfile(str(ex4 / 'stest2.txt')) is True

def test_extract_mem(tmp_path):
    ex1 = tmp_path / "extract11"
    ex2 = tmp_path / "extract22"
    ex3 = tmp_path / "extract33"
    os.makedirs(str(ex1))
    os.makedirs(str(ex2))
    os.makedirs(str(ex3))
    arc = open('test/files/seektest.rar', 'rb').read()
    rf = rarfile.RarFile(io.BytesIO(arc))

    rf.extractall(str(ex1))
    assert os.path.isfile(str(ex1 / 'stest1.txt')) is True
    assert os.path.isfile(str(ex1 / 'stest2.txt')) is True

    rf.extract('stest1.txt', str(ex2))
    assert os.path.isfile(str(ex2 / 'stest1.txt')) is True
    assert os.path.isfile(str(ex2 / 'stest2.txt')) is False

    inf = rf.getinfo('stest2.txt')
    rf.extract(inf, str(ex3))
    assert os.path.isfile(str(ex3 / 'stest1.txt')) is False
    assert os.path.isfile(str(ex3 / 'stest2.txt')) is True

def test_infocb():
    infos = []
    def info_cb(info):
        infos.append( (info.type, info.needs_password(), info.isdir(), info._must_disable_hack()) )

    rf = rarfile.RarFile('test/files/seektest.rar', info_callback=info_cb)
    assert infos == [
        (rarfile.RAR_BLOCK_MAIN, False, False, False),
        (rarfile.RAR_BLOCK_FILE, False, False, False),
        (rarfile.RAR_BLOCK_FILE, False, False, False),
        (rarfile.RAR_BLOCK_ENDARC, False, False, False)]

    infos = []
    rf = rarfile.RarFile('test/files/rar5-solid-qo.rar', info_callback=info_cb)
    assert infos == [
        (rarfile.RAR_BLOCK_MAIN, False, False, True),
        (rarfile.RAR_BLOCK_FILE, False, False, False),
        (rarfile.RAR_BLOCK_FILE, False, False, True),
        (rarfile.RAR_BLOCK_FILE, False, False, True),
        (rarfile.RAR_BLOCK_FILE, False, False, True),
        (rarfile.RAR_BLOCK_SUB, False, False, False),
        (rarfile.RAR_BLOCK_ENDARC, False, False, False)]

def install_alt_tool():
    rarfile.ORIG_UNRAR_TOOL = 'x_unrar_missing'
    rarfile._check_unrar_tool()

def uninstall_alt_tool():
    rarfile.ORIG_UNRAR_TOOL = 'unrar'
    rarfile._check_unrar_tool()

def test_read_rar3():
    with rarfile.RarFile('test/files/seektest.rar') as rf:
        for fn in rf.namelist():
            rf.read(fn)

#@with_setup(install_alt_tool, uninstall_alt_tool)
def test_alt_tool():
    #test_read_rar3()
    pass

