# -*- coding: utf-8 -*-

import glob
import os.path as op
import os
import re
import warnings

import pytest

from codespell_lib._codespell import _builtin_dictionaries
from codespell_lib._codespell import supported_languages

spellers = dict()

try:
    import aspell
    for lang in supported_languages:
        spellers[lang] = aspell.Speller('lang', lang)
except Exception as exp:  # probably ImportError, but maybe also language
    if os.getenv('REQUIRE_ASPELL', 'false').lower() == 'true':
        raise RuntimeError(
            'Cannot run complete tests without aspell when '
            'REQUIRE_ASPELL=true. Got error during import:\n%s'
            % (exp,))
    else:
        warnings.warn(
            'aspell not found, but not required, skipping aspell tests. Got '
            'error during import:\n%s' % (exp,))

global_err_dicts = dict()
global_pairs = set()

# Filename, should be seen as errors in aspell or not
_data_dir = op.join(op.dirname(__file__), '..', 'data')
_fnames_in_aspell = [
    (op.join(_data_dir, 'dictionary%s.txt' % d[2]), d[3:5], d[5:7])
    for d in _builtin_dictionaries]
fname_params = pytest.mark.parametrize('fname, in_aspell, in_dictionary', _fnames_in_aspell)  # noqa: E501


def test_dictionaries_exist():
    """Test consistency of dictionaries."""
    doc_fnames = set(op.basename(f[0]) for f in _fnames_in_aspell)
    got_fnames = set(op.basename(f)
                     for f in glob.glob(op.join(_data_dir, '*.txt')))
    assert doc_fnames == got_fnames


@fname_params
def test_dictionary_formatting(fname, in_aspell, in_dictionary):
    """Test that all dictionary entries are valid."""
    errors = list()
    with open(fname, 'rb') as fid:
        for line in fid:
            err, rep = line.decode('utf-8').split('->')
            err = err.lower()
            rep = rep.rstrip('\n')
            try:
                _check_err_rep(err, rep, in_aspell, fname, in_dictionary)
            except AssertionError as exp:
                errors.append(str(exp).split('\n')[0])
    if len(errors):
        raise AssertionError('\n' + '\n'.join(errors))


def _check_aspell(phrase, msg, in_aspell, fname, languages):
    if not spellers:  # if no spellcheckers exist
        return  # cannot check
    if in_aspell is None:
        return  # don't check
    if ' ' in phrase:
        for word in phrase.split():
            _check_aspell(word, msg, in_aspell, fname, languages)
        return  # stop normal checking as we've done each word above
    this_in_aspell = any(spellers[lang].check(phrase.encode(
        spellers[lang].ConfigKeys()['encoding'][1])) for lang in languages)
    end = 'be in aspell dictionaries (%s) for dictionary %s' % (
        ', '.join(languages), fname)
    if in_aspell:  # should be an error in aspell
        assert this_in_aspell, '%s should %s' % (msg, end)
    else:  # shouldn't be
        assert not this_in_aspell, '%s should not %s' % (msg, end)


whitespace = re.compile(r'\s')
start_whitespace = re.compile(r'^\s')
start_comma = re.compile(r'^,')
whitespace_comma = re.compile(r'\s,')
comma_whitespaces = re.compile(r',\s\s')
comma_without_whitespace = re.compile(r',[^ ]')
whitespace_end = re.compile(r'\s+$')
single_comma = re.compile(r'^[^,]*,\s*$')


def _check_err_rep(err, rep, in_aspell, fname, languages):
    assert whitespace.search(err) is None, 'error %r has whitespace' % err
    assert ',' not in err, 'error %r has a comma' % err
    assert len(rep) > 0, ('error %s: correction %r must be non-empty'
                          % (err, rep))
    assert not start_whitespace.match(rep), ('error %s: correction %r '
                                             'cannot start with whitespace'
                                             % (err, rep))
    _check_aspell(err, 'error %r' % (err,), in_aspell[0], fname, languages[0])
    prefix = 'error %s: correction %r' % (err, rep)
    for (r, msg) in [
            (start_comma,
             '%s starts with a comma'),
            (whitespace_comma,
             '%s contains a whitespace character followed by a comma'),
            (comma_whitespaces,
             '%s contains a comma followed by multiple whitespace characters'),
            (comma_without_whitespace,
             '%s contains a comma *not* followed by a space'),
            (whitespace_end,
             '%s has a trailing space'),
            (single_comma,
             '%s has a single entry but contains a trailing comma')]:
        assert not r.search(rep), (msg % (prefix,))
    del msg
    if rep.count(','):
        assert rep.endswith(','), ('error %s: multiple corrections must end '
                                   'with trailing ","' % (err,))
    reps = [r.strip() for r in rep.split(',')]
    reps = [r for r in reps if len(r)]
    for r in reps:
        assert err != r.lower(), ('error %r corrects to itself amongst others'
                                  % (err,))
        _check_aspell(
            r, 'error %s: correction %r' % (err, r),
            in_aspell[1], fname, languages[1])

    # aspell dictionary is case sensitive, so pass the original case into there
    # we could ignore the case, but that would miss things like days of the
    # week which we want to be correct
    reps = [r.lower() for r in reps]
    assert len(set(reps)) == len(reps), ('error %s: corrections "%s" are not '
                                         '(lower-case) unique' % (err, rep))


@pytest.mark.parametrize('err, rep, match', [
    ('a a', 'bar', 'has whitespace'),
    ('a,a', 'bar', 'has a comma'),
    ('a', '', 'non-empty'),
    ('a', ' bar', 'start with whitespace'),
    ('a', ',bar', 'starts with a comma'),
    ('a', 'bar,bat', '.*not.*followed by a space'),
    ('a', 'bar ', 'trailing space'),
    ('a', 'b ,ar', 'contains a whitespace.*followed by a comma'),
    ('a', 'bar,', 'single entry.*comma'),
    ('a', 'bar, bat', 'must end with trailing ","'),
    ('a', 'a, bar,', 'corrects to itself amongst others'),
    ('a', 'a', 'corrects to itself'),
    ('a', 'bar, Bar,', 'unique'),
])
def test_error_checking(err, rep, match):
    """Test that our error checking works."""
    with pytest.raises(AssertionError, match=match):
        _check_err_rep(err, rep, (None, None), 'dummy',
                       (supported_languages, supported_languages))


@pytest.mark.skipif(not spellers, reason='requires aspell-en')
@pytest.mark.parametrize('err, rep, err_aspell, rep_aspell, match', [
    # This doesn't raise any exceptions, so skip for now:
    # pytest.param('a', 'uvw, bar,', None, None, 'should be in aspell'),
    ('abcdef', 'uvwxyz, bar,', True, None, 'should be in aspell'),
    ('a', 'uvwxyz, bar,', False, None, 'should not be in aspell'),
    ('a', 'abcdef, uvwxyz,', None, True, 'should be in aspell'),
    ('abcdef', 'uvwxyz, bar,', True, True, 'should be in aspell'),
    ('abcdef', 'uvwxyz, bar,', False, True, 'should be in aspell'),
    ('a', 'bar, back,', None, False, 'should not be in aspell'),
    ('a', 'bar, back, Wednesday,', None, False, 'should not be in aspell'),
    ('abcdef', 'ghijkl, uvwxyz,', True, False, 'should be in aspell'),
    ('abcdef', 'uvwxyz, bar,', False, False, 'should not be in aspell'),
    # Multi-word corrections
    # One multi-word, both parts
    ('a', 'abcdef uvwxyz', None, True, 'should be in aspell'),
    ('a', 'bar back', None, False, 'should not be in aspell'),
    ('a', 'bar back Wednesday', None, False, 'should not be in aspell'),
    # Second multi-word, both parts
    ('a', 'bar back, abcdef uvwxyz, bar,', None, True, 'should be in aspell'),
    ('a', 'abcdef uvwxyz, bar back, ghijkl,', None, False, 'should not be in aspell'),  # noqa: E501
    # One multi-word, second part
    ('a', 'bar abcdef', None, True, 'should be in aspell'),
    ('a', 'abcdef back', None, False, 'should not be in aspell'),
])
def test_error_checking_in_aspell(err, rep, err_aspell, rep_aspell, match):
    """Test that our error checking works with aspell."""
    with pytest.raises(AssertionError, match=match):
        _check_err_rep(
            err, rep, (err_aspell, rep_aspell), 'dummy',
            (supported_languages, supported_languages))


# allow some duplicates, like "m-i-n-i-m-i-s-e", or "c-a-l-c-u-l-a-t-a-b-l-e"
allowed_dups = {
    ('dictionary.txt', 'dictionary_en-GB_to_en-US.txt'),
    ('dictionary.txt', 'dictionary_names.txt'),
    ('dictionary.txt', 'dictionary_rare.txt'),
    ('dictionary.txt', 'dictionary_usage.txt'),
    ('dictionary_rare.txt', 'dictionary_usage.txt'),
}


@fname_params
@pytest.mark.dependency(name='dictionary loop')
def test_dictionary_looping(fname, in_aspell, in_dictionary):
    """Test that all dictionary entries are valid."""
    this_err_dict = dict()
    short_fname = op.basename(fname)
    with open(fname, 'rb') as fid:
        for line in fid:
            err, rep = line.decode('utf-8').split('->')
            err = err.lower()
            assert err not in this_err_dict, \
                'error %r already exists in %s' % (err, short_fname)
            rep = rep.rstrip('\n')
            reps = [r.strip() for r in rep.lower().split(',')]
            reps = [r for r in reps if len(r)]
            this_err_dict[err] = reps
    # 1. check the dict against itself (diagonal)
    for err in this_err_dict:
        for r in this_err_dict[err]:
            assert r not in this_err_dict, \
                ('error %s: correction %s is an error itself in the same '
                 'dictionary file %s' % (err, r, short_fname))
    pair = (short_fname, short_fname)
    assert pair not in global_pairs
    global_pairs.add(pair)
    for other_fname, other_err_dict in global_err_dicts.items():
        # error duplication (eventually maybe we should just merge?)
        for err in this_err_dict:
            assert err not in other_err_dict, \
                ('error %r in dictionary %s already exists in dictionary '
                 '%s' % (err, short_fname, other_fname))
        # 2. check corrections in this dict against other dicts (upper)
        pair = (short_fname, other_fname)
        if pair not in allowed_dups:
            for err in this_err_dict:
                assert err not in other_err_dict, \
                    ('error %r in dictionary %s already exists in dictionary '
                     '%s' % (err, short_fname, other_fname))
                for r in this_err_dict[err]:
                    assert r not in other_err_dict, \
                        ('error %s: correction %s from dictionary %s is an '
                         'error itself in dictionary %s'
                         % (err, r, short_fname, other_fname))
        assert pair not in global_pairs
        global_pairs.add(pair)
        # 3. check corrections in other dicts against this dict (lower)
        pair = (other_fname, short_fname)
        if pair not in allowed_dups:
            for err in other_err_dict:
                for r in other_err_dict[err]:
                    assert r not in this_err_dict, \
                        ('error %s: correction %s from dictionary %s is an '
                         'error itself in dictionary %s'
                         % (err, r, other_fname, short_fname))
        assert pair not in global_pairs
        global_pairs.add(pair)
    global_err_dicts[short_fname] = this_err_dict


@pytest.mark.dependency(depends=['dictionary loop'])
def test_ran_all():
    """Test that all pairwise tests ran."""
    for f1, _, _ in _fnames_in_aspell:
        f1 = op.basename(f1)
        for f2, _, _ in _fnames_in_aspell:
            f2 = op.basename(f2)
            assert (f1, f2) in global_pairs
    assert len(global_pairs) == len(_fnames_in_aspell) ** 2
