from flask import Flask, render_template, request, jsonify
import secrets
import os
import time
import jwt

app = Flask(__name__)

JWT_ALG = "HS256"
CHECKER_URL = os.environ.get("CHECKER_URL", "http://checker:9090/get_flag")
JWT_SECRET_MIN_LEN = int(os.environ.get("JWT_SECRET_MIN_LEN", "32"))

USERS = {
    "guest": {"password": "guest123", "role": "traveler"},
    "officer": {"password": "officer_only", "role": "officer"},
}

# БЛОК ДЛЯ РЕДАКТИРОВАНИЯ:

def load_jwt_secret() -> str:
    secret = os.environ.get("JWT_SECRET")
    if not secret:
        raise RuntimeError("JWT_SECRET is not set")
    return secret

def verify_token(token: str):
    try:
        return jwt.decode(token, options={"verify_signature": False, "verify_exp": False})
    except Exception:
        return None
    
# КОНЕЦ БЛОКА ДЛЯ РЕДАКТИРОВАНИЯ:

JWT_SECRET = load_jwt_secret()


def issue_token(username: str, role: str) -> str:
    payload = {
        "sub": username,
        "role": role,
        "iat": int(time.time()),
        "exp": int(time.time()) + 3600,
    }
    return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALG)


def get_bearer_token() -> str:
    auth = request.headers.get("Authorization", "")
    if auth.startswith("Bearer "):
        return auth[7:]
    return ""


@app.route("/", methods=["GET"])
def index():
    return render_template("index.html")


@app.route("/api/login", methods=["POST"])
def login():
    data = request.get_json(silent=True) or {}
    username = data.get("username", "")
    password = data.get("password", "")

    user = USERS.get(username)
    if not user or user["password"] != password:
        return jsonify({"error": "Invalid credentials"}), 401

    token = issue_token(username, user["role"])
    return jsonify({"token": token, "role": user["role"]})


@app.route("/api/profile", methods=["GET"])
def profile():
    token = get_bearer_token()
    if not token:
        return jsonify({"error": "Missing token"}), 401

    claims = verify_token(token)
    if not claims:
        return jsonify({"error": "Invalid token"}), 401

    return jsonify({"sub": claims.get("sub"), "role": claims.get("role")})


@app.route("/api/control", methods=["GET"])
def control():
    token = get_bearer_token()
    if not token:
        return jsonify({"error": "Missing token"}), 401

    claims = verify_token(token)
    if not claims:
        return jsonify({"error": "Invalid token"}), 401

    if claims.get("role") != "officer":
        return jsonify({"error": "Access denied"}), 403

    return jsonify({"status": "EMERALD_GATE_OPEN"})


@app.route("/api/security", methods=["GET"])
def security():
    return jsonify({
        "jwt_secret_length": len(JWT_SECRET),
        "jwt_secret_min_length": JWT_SECRET_MIN_LEN,
    })


@app.route("/flag", methods=["GET"])
def flag():
    import requests

    try:
        resp = requests.get(CHECKER_URL, timeout=3)
        data = resp.json()
        if data.get("status") == "fixed" and data.get("flag"):
            return render_template("index.html", flag=data.get("flag"))
        return render_template("index.html", error=data.get("message", "Fix not accepted yet."))
    except requests.exceptions.RequestException as exc:
        return render_template("index.html", error=f"Checker error: {exc}"), 502


if __name__ == "__main__":
    port = int(os.environ.get("PORT", "8080"))
    app.run(host="0.0.0.0", port=port)
