# barbacompta - accounting for dummies
# Copyright (C) 2010-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _


def validate_luhn(string_value, length=None):
    '''Verify Luhn checksum on a string representing a number'''
    if not string_value:
        return False
    if length is not None and len(string_value) != length:
        return False
    if not string_value.isdigit():
        return False

    # take all digits counting from the right, double value for digits pair
    # index (counting from 1), if double has 2 digits take their sum
    checksum = 0
    for i, x in enumerate(reversed(string_value)):
        if i % 2 == 0:
            checksum += int(x)
        else:
            checksum += sum(int(y) for y in str(2 * int(x)))
    if checksum % 10 != 0:
        return False
    return True


def validate_siren(string_value):
    if not validate_luhn(string_value, length=9):
        raise ValidationError(_('invalid SIREN'))


def validate_siret(string_value):
    # special case : La Poste
    def helper():
        if not string_value.isdigit():
            return False
        if (
            string_value.startswith('356000000')
            and len(string_value) == 14
            and sum(int(x) for x in string_value) % 5 == 0
        ):
            return True
        return validate_luhn(string_value, length=14)

    if not helper():
        raise ValidationError(_('invalid SIRET'))
