# -*- coding: utf-8 -*-


import flask
import json
from flask_jwt_extended import jwt_required, get_current_user
from pritunl_dedicated.blueprints import api_version
from pritunl_dedicated.models.pritunl_dedicated import Version
from pritunl_dedicated.extensions import db
from pritunl_dedicated.tools.helpers import int_to_version
from pritunl_dedicated.views.api import filter_to_sqlalchemy, sort_to_sqlalchemy


__author__ = "Adam Schubert"
__date__ = "$18.8.2014 23:33:05$"


@api_version.route('', methods=['GET'], defaults={'page': 1})
@api_version.route('/page/<int:page>', methods=['GET'])
@jwt_required
def get_versions(page: int):

    order_by = sort_to_sqlalchemy(
        Version,
        flask.request.args.get('sort_field'),
        int(flask.request.args.get('sort_order', 1)),
        {
            'version_string': 'version_string',
            'version_integer': 'version_integer'
        },
        'created'
    )

    subscriptions = Version.query.order_by(order_by)

    per_page = int(flask.request.args['per_page']) if 'per_page' in flask.request.args else subscriptions.count()
    filters = json.loads(flask.request.args['filters']) if 'filters' in flask.request.args else {}
    subscriptions_filter = filter_to_sqlalchemy(
        Version,
        filters,
        {
            'version_string': 'version_string',
            'version_integer': 'version_integer'
        }
    )

    paginator = subscriptions.filter(*subscriptions_filter).paginate(page, per_page)

    data_ret = []
    for subscription in paginator.items:
        data_ret.append(subscription.jsonify())

    ret = {
        'has_next': paginator.has_next,
        'has_prev': paginator.has_prev,
        'next_num': paginator.next_num,
        'prev_num': paginator.prev_num,
        'page': paginator.page,
        'pages': paginator.pages,
        'per_page': paginator.per_page,
        'total': paginator.total,
        'data': data_ret,
        'next': flask.url_for('api.version.get_versions', page=paginator.next_num, _external=True),
        'prev': flask.url_for('api.version.get_versions', page=paginator.prev_num, _external=True)
    }

    return flask.jsonify(ret), 200


@api_version.route('', methods=['PUT'])
@jwt_required
def set_version():
    version_id = flask.request.json.get('id')
    version_integer = int(flask.request.json.get('version_integer'))
    version_string = flask.request.json.get('version_string')

    if int_to_version(version_integer) != version_string:
        return flask.jsonify({'message': 'Version integer do not match version string'}), 400

    version_found = Version.query.filter_by(id=version_id).first()
    if not version_found:
        return flask.jsonify({'message': 'Version not found'}), 404

    version_integer_found = Version.query.filter_by(version_integer=version_integer).first()
    if version_integer_found and version_integer_found != version_found:
        return flask.jsonify({'message': 'Version integer found'}), 409

    version_found.version_integer = version_integer
    version_found.version_string = version_string

    db.session.add(version_found)
    db.session.commit()

    return flask.jsonify(version_found.jsonify()), 200


@api_version.route('', methods=['POST'])
@jwt_required
def create_version():
    version_integer = int(flask.request.json.get('version_integer'))
    version_string = flask.request.json.get('version_string')

    if int_to_version(version_integer) != version_string:
        return flask.jsonify({'message': 'Version integer do not match version string'}), 400

    version_integer_found = Version.query.filter_by(version_integer=version_integer).first()
    if version_integer_found:
        return flask.jsonify({'message': 'Version found'}), 409

    new_subscription = Version()
    new_subscription.version_integer = version_integer
    new_subscription.version_string = version_string

    db.session.add(new_subscription)
    db.session.commit()

    return flask.jsonify(new_subscription.jsonify()), 200


@api_version.route('/<int:version_id>', methods=['DELETE'])
@jwt_required
def delete_version(version_id: int):
    version_found = Version.query.filter_by(id=version_id).first()
    if not version_found:
        return flask.jsonify({'message': 'Version not found'}), 404
    db.session.delete(version_found)
    db.session.commit()
    return flask.jsonify(version_found.jsonify()), 200


@api_version.route('/<int:version_id>', methods=['GET'])
@jwt_required
def get_version(version_id: int):
    version_found = Version.query.filter_by(id=version_id).first()
    if not version_found:
        return flask.jsonify({'message': 'Version not found'}), 404

    return flask.jsonify(version_found.jsonify()), 200
