# Path: hashview/models.py
# class Customers(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(40), nullable=False)
# 
# class HashfileHashes(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     hash_id = db.Column(db.Integer, nullable=False, index=True)
#     username = db.Column(db.String(256), nullable=True, default=None, index=True)
#     hashfile_id = db.Column(db.Integer, nullable=False)
# 
# class Hashes(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     sub_ciphertext = db.Column(db.String(32), nullable=False, index=True)
#     ciphertext = db.Column(db.String(16383), nullable=False) # Setting this to max value for now. If we run into this being a limitation in the future we can revisit changing thist to TEXT or BLOB. https://sheeri.org/max-varchar-size/
#     hash_type = db.Column(db.Integer, nullable=False, index=True)
#     cracked = db.Column(db.Boolean, nullable=False)
#     plaintext = db.Column(db.String(256), index=True)
# 
# class Hashfiles(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(256), nullable=False)        # can probably be reduced
#     uploaded_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
#     runtime = db.Column(db.Integer, default=0)
#     customer_id = db.Column(db.Integer, nullable=False)
#     owner_id = db.Column(db.Integer, nullable=False)
# 
# Path: hashview.py
# def data_retention_cleanup():


from flask import Blueprint, jsonify, render_template, request, redirect, send_from_directory
from flask_login import login_required
from hashview.models import Customers, HashfileHashes, Hashes, Hashfiles
from hashview import db
import re
import operator
            fig2_uncracked_cnt = db.session.query(Hashes, HashfileHashes).join(HashfileHashes, Hashes.id==HashfileHashes.hash_id).join(Hashfiles, HashfileHashes.hashfile_id==Hashfiles.id).filter(Hashfiles.customer_id == customer_id).filter(Hashes.cracked == '0').count()
    else:
        fig2_cracked_hashes = db.session.query(Hashes, HashfileHashes).join(HashfileHashes, Hashes.id==HashfileHashes.hash_id).filter(Hashes.cracked=='1').with_entities(Hashes.plaintext).all()
        fig2_uncracked_cnt = db.session.query(Hashes, HashfileHashes).join(HashfileHashes, Hashes.id==HashfileHashes.hash_id).filter(Hashes.cracked=='0').count()
    
    fig2_fails_complexity_cnt = 0
    fig2_meets_complexity_cnt = 0

    for entry in fig2_cracked_hashes:
        flags = 0
        if len(bytes.fromhex(entry[0]).decode('latin-1')) < 8:
            flags = -3 # set to negative 3 so that there's no way we can meet complexity
        if re.search(r"[a-z]", bytes.fromhex(entry[0]).decode('latin-1')):
            flags = flags + 1
        if re.search(r"[A-Z]", bytes.fromhex(entry[0]).decode('latin-1')):
            flags = flags + 1
        if re.search(r"[0-9]", bytes.fromhex(entry[0]).decode('latin-1')):
            flags = flags + 1
        if re.search(r"[^0-9A-Za-z]", bytes.fromhex(entry[0]).decode('latin-1')):
            flags = flags + 1
        
        if flags < 3:
            fig2_fails_complexity_cnt = fig2_fails_complexity_cnt + 1
        else:
            fig2_meets_complexity_cnt = fig2_meets_complexity_cnt + 1
    
    fig2_data = [
        ("Fails Complexity: " + str(formatDisplay(fig2_fails_complexity_cnt)), fig2_fails_complexity_cnt),
        ("Meets Complexity: " + str(formatDisplay(fig2_meets_complexity_cnt)), fig2_meets_complexity_cnt),
        ("Unrecovered: " + str(formatDisplay(fig2_uncracked_cnt)), fig2_uncracked_cnt)

# Path: hashview/models.py
# class Customers(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(40), nullable=False)
# 
# class HashfileHashes(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     hash_id = db.Column(db.Integer, nullable=False, index=True)
#     username = db.Column(db.String(256), nullable=True, default=None, index=True)
#     hashfile_id = db.Column(db.Integer, nullable=False)
# 
# class Hashes(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     sub_ciphertext = db.Column(db.String(32), nullable=False, index=True)
#     ciphertext = db.Column(db.String(16383), nullable=False) # Setting this to max value for now. If we run into this being a limitation in the future we can revisit changing thist to TEXT or BLOB. https://sheeri.org/max-varchar-size/
#     hash_type = db.Column(db.Integer, nullable=False, index=True)
#     cracked = db.Column(db.Boolean, nullable=False)
#     plaintext = db.Column(db.String(256), index=True)
# 
# class Hashfiles(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(256), nullable=False)        # can probably be reduced
#     uploaded_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
#     runtime = db.Column(db.Integer, default=0)
#     customer_id = db.Column(db.Integer, nullable=False)
#     owner_id = db.Column(db.Integer, nullable=False)
# 
# Path: hashview.py
# def data_retention_cleanup():


# Path: hashview/analytics/routes.py
from flask import Blueprint, jsonify, render_template, request, redirect, send_from_directory
from flask_login import login_required
from hashview.models import Customers, HashfileHashes, Hashes, Hashfiles
from hashview import db
import re
import operator

            fig2_uncracked_cnt = db.session.query(Hashes, HashfileHashes).join(HashfileHashes, Hashes.id==HashfileHashes.hash_id).join(Hashfiles, HashfileHashes.hashfile_id==Hashfiles.id).filter(Hashfiles.customer_id == customer_id).filter(Hashes.cracked == '0').count()
    else:
        fig2_cracked_hashes = db.session.query(Hashes, HashfileHashes).join(HashfileHashes, Hashes.id==HashfileHashes.hash_id).filter(Hashes.cracked=='1').with_entities(Hashes.plaintext).all()
        fig2_uncracked_cnt = db.session.query(Hashes, HashfileHashes).join(HashfileHashes, Hashes.id==HashfileHashes.hash_id).filter(Hashes.cracked=='0').count()
    
    fig2_fails_complexity_cnt = 0
    fig2_meets_complexity_cnt = 0

    for entry in fig2_cracked_hashes:
        flags = 0
        if len(bytes.fromhex(entry[0]).decode('latin-1')) < 8:
            flags = -3 # set to negative 3 so that there's no way we can meet complexity
        if re.search(r"[a-z]", bytes.fromhex(entry[0]).decode('latin-1')):
            flags = flags + 1
        if re.search(r"[A-Z]", bytes.fromhex(entry[0]).decode('latin-1')):
            flags = flags + 1
        if re.search(r"[0-9]", bytes.fromhex(entry[0]).decode('latin-1')):
            flags = flags + 1
        if re.search(r"[^0-9A-Za-z]", bytes.fromhex(entry[0]).decode('latin-1')):
            flags = flags + 1
        
        if flags < 3:
            fig2_fails_complexity_cnt = fig2_fails_complexity_cnt + 1
        else:
            fig2_meets_complexity_cnt = fig2_meets_complexity_cnt + 1
    
    fig2_data = [
        ("Fails Complexity: " + str(formatDisplay(fig2_fails_complexity_cnt)), fig2_fails_complexity_cnt),
        ("Meets Complexity: " + str(formatDisplay(fig2_meets_complexity_cnt)), fig2_meets_complexity_cnt),
        ("Unrecovered: " + str(formatDisplay(fig2_uncracked_cnt)), fig2_uncracked_cnt)

    ]