#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""Test script.

This script executes the unit tests for the package.
"""

from unittest import TestCase, main
from pathlib import Path
from subprocess import run, DEVNULL
from tempfile import TemporaryDirectory
from shutil import copytree
from contextlib import contextmanager

from pashword.core import sets, hash, book

dir_tests = Path(__file__).parent
dir_target = dir_tests/'target'
dir_inputs = dir_tests/'inputs'

def runcheck(command: str, **kwargs) -> None:
    run(command, shell=True, check=True, stdout=DEVNULL, **kwargs)

@contextmanager
def temporary_target():
    temp_dir = TemporaryDirectory()
    path = Path(temp_dir.name)
    copytree(dir_target, path, dirs_exist_ok=True)
    try:
        yield path
    finally:
        temp_dir.cleanup()

class TestCore(TestCase):

    def test_metacharacters(self):
        stored = 'ABCDEFGHJKLMNPRSTUVWXYZ'
        self.assertEqual(stored, sets.get('u'))
        stored = 'ABCDEFGHJKLMNPRSTUVWXYZ23456789abcdefghijkmnopqrstuvwxyz'
        self.assertEqual(stored, sets.get('*'))
        self.assertEqual('-', sets.get('-'))

    def test_combinations(self):
        self.assertEqual(1, sets.combinations('a'))
        self.assertEqual(1, sets.combinations('ab'))
        self.assertEqual(8, sets.combinations('d'))
        self.assertEqual(8**2, sets.combinations('dd'))

    def test_hexdigest(self):
        stored = '8342d2719fa5821c254d6484cfc0716fc1e01b8e290ea575187762fc428d14bd293db60510a7d17e09a714d8aec70c6f5e430a966c499e3d1ad3dede7feb2e32'
        self.assertEqual(stored, hash.hexdigest('key', 'salt'))

    def test_password(self):
        stored = '5YhNDd77dZ8us6du'
        self.assertEqual(stored, hash.password('key', 'salt', '*'*16))

    def test_same(self):
        with temporary_target() as target:
            key = 'key'
            path = target/'validate.json'
            hash.save(key, path)
            self.assertTrue(hash.same(key, path))

    def test_load(self):
        with temporary_target() as target:
            data = book.load(target/'user.conf')

    def test_filter(self):
        data = {'n1': {'form': '1'}, 'n2': {'form': '2'}}
        stored = {'n1': {'form': '1'}}
        self.assertEqual(stored, book.filter(data, '*1'))

    def test_decode(self):
        with temporary_target() as target:
            data = book.load(target/'user.conf')
            decoded = book.decode(data, "secret key")
            stored = 'B2nG-hLAe-5Pom'
            self.assertEqual(stored, decoded['entity-one.org']['password'])

class TestMain(TestCase):

    def test_sort(self):
        pass

class TestCommandLineInterface(TestCase):

    def test_help(self):
        runcheck("pashword --help")
        runcheck("pashword read --help")
        runcheck("pashword sort --help")

    def test_features(self):
        with temporary_target() as target:
            book = target/'user.conf'
            hash = target/'user.json'
            runcheck(f"pashword read --book {book} < {dir_inputs/'read.txt'}")
            runcheck(f"pashword read --book {book} --hash {hash} < {dir_inputs/'read.txt'}")
            runcheck(f"pashword read --book {book} --hash {hash} < {dir_inputs/'read.txt'}")
            runcheck(f"pashword sort --book {book} < {dir_inputs/'read.txt'}")
            runcheck(f"pashword read --book {book} < {dir_inputs/'read.txt'}")

if __name__ == '__main__':
    main(buffer=True)
