from flask import abort, current_app
from flask_login import current_user, login_required
from threading import Thread
import os
from app import db
from app.decorators import admin_required, content_negotiation
from app.models import Job, JobStatus
from . import bp


@bp.route('/<hashid:job_id>', methods=['DELETE'])
@login_required
@content_negotiation(produces='application/json')
def delete_job(job_id):
    def _delete_job(app, job_id):
        with app.app_context():
            job = Job.query.get(job_id)
            job.delete()
            db.session.commit()

    job = Job.query.get_or_404(job_id)
    if not (job.user == current_user or current_user.is_administrator()):
        abort(403)
    thread = Thread(
        target=_delete_job,
        args=(current_app._get_current_object(), job_id)
    )
    thread.start()
    response_data = {
        'message': f'Job "{job.title}" marked for deletion'
    }
    return response_data, 202


@bp.route('/<hashid:job_id>/log')
@login_required
@admin_required
@content_negotiation(produces='application/json')
def job_log(job_id):
    job = Job.query.get_or_404(job_id)
    if job.status not in [JobStatus.COMPLETED, JobStatus.FAILED]:
        response = {'errors': {'message': 'Job status is not completed or failed'}}
        return response, 409
    with open(os.path.join(job.path, 'pipeline_data', 'logs', 'pyflow_log.txt')) as log_file:
        log = log_file.read()
    response_data = {
        'message': '',
        'jobLog': log
    }
    return response_data, 200


@bp.route('/<hashid:job_id>/restart', methods=['POST'])
@login_required
@content_negotiation(produces='application/json')
def restart_job(job_id):
    def _restart_job(app, job_id):
        with app.app_context():
            job = Job.query.get(job_id)
            job.restart()
            db.session.commit()

    job = Job.query.get_or_404(job_id)
    if not (job.user == current_user or current_user.is_administrator()):
        abort(403)
    if job.status == JobStatus.FAILED:
        response = {'errors': {'message': 'Job status is not "failed"'}}
        return response, 409
    thread = Thread(
        target=_restart_job,
        args=(current_app._get_current_object(), job_id)
    )
    thread.start()
    response_data = {
        'message': f'Job "{job.title}" marked for restarting'
    }
    return response_data, 202
