# -*- coding: utf-8 -*-
import binascii
import os
import uuid
import sqlite3

from params import param_dict
from vial import render_template
import math
import bcrypt
from redirect import redirect
from cookie import tk_pass


def change(headers, body, data, token=''):
    cookie = str(headers['http-cookie']).replace('sessionid=', '')
    current = str(data['current']) if 'current' in data else ''
    password1 = str(data['password1']) if 'password1' in data else ''
    password2 = str(data['password2']) if 'password2' in data else ''
    if token == '':
        token = str(data['token']) if 'token' in data else ''
    db_password = tk_pass(token, cookie)
    if current == '' or password1 == '' or password2 == '':
        return render_template('templates/change.html', body=body, data=data, token=token), 200, {}
    elif db_password == '':
        return redirect(headers=headers, body=body, data=data, message='Unauthorized password change request')
    salt = db_password[0:29]
    for i in range(3):
        current = bcrypt.hashpw(current, salt)

    if current != db_password:
        return render_template('templates/change.html', body=body, data=data, token=token, message='Current password is incorrect'), 200, {}
    elif password1 != password2:
        return render_template('templates/change.html', body=body, data=data, token=token, message='Passwords must be identical'), 200, {}
    elif not pass_correct_length(password1):
        return render_template('templates/change.html', body=body, data=data,  token=token, message='New password length should be 6-24 characters'), 200, {}
    elif pass_entropy(password1) < 50.0:
        return render_template('templates/change.html', body=body, data=data, token=token, message='New password is too simple. Entropy: ' + str(round(pass_entropy(password1), 2))), 200, {}
    salt = bcrypt.gensalt()
    for i in range(3):
        password1 = bcrypt.hashpw(password1, salt)
    new_token = str(uuid.UUID(hex=binascii.b2a_hex(os.urandom(16))))

    conn = sqlite3.connect(param_dict['db_file'])
    cursor = conn.cursor()

    cursor.execute("UPDATE users SET password=?, token=? WHERE token=?;", (password1, new_token, token))
    conn.commit()
    return redirect(headers=headers, body=body, data=data, message='Password has been successfully changed')


def pass_entropy(password):
    small = big = num = spec = 0
    for c in password:
        if 96 < ord(c) < 123:
            small = 1
        elif 64 < ord(c) < 91:
            big = 1
        elif 47 < ord(c) < 58:
            num = 1
        else:
            spec = 1
    alpha = small * 26 + big * 26 + num * 10 + spec * 66
    entropy = len(password) * math.log(alpha if alpha > 0 else 1, 2)
    return entropy


def pass_correct_length(password):
    if 6 <= len(password) <= 24:
        return True
    return False