# Path: hashview/models.py
# 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)
# 
# class Customers(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(40), nullable=False)
# 
# class Jobs(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(50), nullable=False)
#     created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
#     updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
#     status = db.Column(db.String(20), nullable=False)           # Running, Paused, Completed, Queued, Canceled, Ready, Incomplete
#     started_at = db.Column(db.DateTime, nullable=True)          # These defaults should be changed
#     ended_at = db.Column(db.DateTime, nullable=True)            # These defaults should be changed
#     hashfile_id = db.Column(db.Integer, nullable=True)
#     customer_id = db.Column(db.Integer, db.ForeignKey('customers.id'), nullable=False)
#     owner_id = db.Column(db.Integer, db.ForeignKey('users.id'), 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 HashNotifications(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     owner_id = db.Column(db.Integer, nullable=False)
#     hash_id = db.Column(db.Integer, nullable=False)
#     method = db.Column(db.String(6), nullable=False)    # email, push
# 
# 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)
# 
# Path: hashview.py
# def data_retention_cleanup():


from flask import Blueprint, render_template, url_for, redirect, flash
from flask_login import login_required, current_user
from hashview.models import Hashfiles, Customers, Jobs, HashfileHashes, HashNotifications, Hashes
from hashview import db
    return render_template('hashfiles.html', title='Hashfiles', hashfiles=hashfiles, customers=customers, cracked_rate=cracked_rate, jobs=jobs, hash_type_dict=hash_type_dict)

@hashfiles.route("/hashfiles/delete/<int:hashfile_id>", methods=['GET', 'POST'])
@login_required
def hashfiles_delete(hashfile_id):
    hashfile = Hashfiles.query.get_or_404(hashfile_id)
    jobs = Jobs.query.filter_by(hashfile_id = hashfile_id).first()

    if hashfile:
        if current_user.admin or hashfile.owner_id == current_user.id:
            if jobs:
                flash('Error: Hashfile currently associated with a job.', 'danger')
                return redirect(url_for('hashfiles.hashfiles_list'))
            else:
                hashfile_hashes = HashfileHashes.query.filter_by(hashfile_id = hashfile_id).all()
                for hashfile_hash in hashfile_hashes:
                    hashes = Hashes.query.filter_by(id=hashfile_hash.hash_id).filter_by(cracked=0)
                    for hash in hashes:
                        # Check to see if our hashfile is the ONLY hashfile that has this hash
                        # if duplicates exist, they can still be removed. Once the hashfile_hash entry is remove, 
                        # the total number of matching hash_id's will be reduced to < 2 and then can be deleted
                        hashfile_cnt = HashfileHashes.query.filter_by(hash_id=hash.id).distinct('hashfile_id').count()
                        if hashfile_cnt < 2:
                            db.session.delete(hash)
                            db.session.commit()
                        HashNotifications.query.filter_by(hash_id=hashfile_hash.hash_id).delete()
                    #db.session.delete(hashes)
                    db.session.delete(hashfile_hash)
                db.session.delete(hashfile)
                db.session.commit()

# Path: hashview/models.py
# 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)
# 
# class Customers(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(40), nullable=False)
# 
# class Jobs(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(50), nullable=False)
#     created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
#     updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
#     status = db.Column(db.String(20), nullable=False)           # Running, Paused, Completed, Queued, Canceled, Ready, Incomplete
#     started_at = db.Column(db.DateTime, nullable=True)          # These defaults should be changed
#     ended_at = db.Column(db.DateTime, nullable=True)            # These defaults should be changed
#     hashfile_id = db.Column(db.Integer, nullable=True)
#     customer_id = db.Column(db.Integer, db.ForeignKey('customers.id'), nullable=False)
#     owner_id = db.Column(db.Integer, db.ForeignKey('users.id'), 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 HashNotifications(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     owner_id = db.Column(db.Integer, nullable=False)
#     hash_id = db.Column(db.Integer, nullable=False)
#     method = db.Column(db.String(6), nullable=False)    # email, push
# 
# 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)
# 
# Path: hashview.py
# def data_retention_cleanup():


# Path: hashview/hashfiles/routes.py
from flask import Blueprint, render_template, url_for, redirect, flash
from flask_login import login_required, current_user
from hashview.models import Hashfiles, Customers, Jobs, HashfileHashes, HashNotifications, Hashes
from hashview import db

    return render_template('hashfiles.html', title='Hashfiles', hashfiles=hashfiles, customers=customers, cracked_rate=cracked_rate, jobs=jobs, hash_type_dict=hash_type_dict)

@hashfiles.route("/hashfiles/delete/<int:hashfile_id>", methods=['GET', 'POST'])
@login_required
def hashfiles_delete(hashfile_id):
    hashfile = Hashfiles.query.get_or_404(hashfile_id)
    jobs = Jobs.query.filter_by(hashfile_id = hashfile_id).first()

    if hashfile:
        if current_user.admin or hashfile.owner_id == current_user.id:
            if jobs:
                flash('Error: Hashfile currently associated with a job.', 'danger')
                return redirect(url_for('hashfiles.hashfiles_list'))
            else:
                hashfile_hashes = HashfileHashes.query.filter_by(hashfile_id = hashfile_id).all()
                for hashfile_hash in hashfile_hashes:
                    hashes = Hashes.query.filter_by(id=hashfile_hash.hash_id).filter_by(cracked=0)
                    for hash in hashes:
                        # Check to see if our hashfile is the ONLY hashfile that has this hash
                        # if duplicates exist, they can still be removed. Once the hashfile_hash entry is remove, 
                        # the total number of matching hash_id's will be reduced to < 2 and then can be deleted
                        hashfile_cnt = HashfileHashes.query.filter_by(hash_id=hash.id).distinct('hashfile_id').count()
                        if hashfile_cnt < 2:
                            db.session.delete(hash)
                            db.session.commit()
                        HashNotifications.query.filter_by(hash_id=hashfile_hash.hash_id).delete()
                    #db.session.delete(hashes)
                    db.session.delete(hashfile_hash)
                db.session.delete(hashfile)
                db.session.commit()

                flash('Hashfile has been deleted!', 'success')