from flask import Flask, Response, abort, render_template, send_file
from flask_cors import CORS
from pymbtiles import MBtiles
import os

from cachetools import LRUCache

tile_cache = LRUCache(maxsize=5000)

app = Flask(__name__)
CORS(app)

MBTILES_PATH = os.path.join(app.root_path, "static", "data-files/cobertura.mbtiles")

def flip_y(z, y):
    return (1 << z) - 1 - y

@app.route("/")
def index():
    return render_template("index.html")


@app.route("/tiles/<int:z>/<int:x>/<int:y>.pbf")
def tiles(z, x, y):
    y = flip_y(z, y)
    key = (z, x, y)

    if key in tile_cache:
        tile = tile_cache[key]
    else:
        with MBtiles(MBTILES_PATH) as mbtiles:
            tile = mbtiles.read_tile(z, x, y)
        if tile is None:
            abort(404)
        if isinstance(tile, tuple):
            tile = tile[0]
        tile_cache[key] = tile

    return Response(
        tile,
        mimetype="application/x-protobuf",
        headers={
            "Content-Encoding": "gzip",
            "Cache-Control": "public, max-age=86400"
        }
    )

    # return Response(
    #     tile,
    #     mimetype="application/x-protobuf",
    #     headers={
    #         "Content-Encoding": "gzip",
    #         "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0"
    #     }
    # )


@app.route("/api/poligonos-edos")
def poligonos_edos():
    response = send_file(
        os.path.join(app.root_path, "static/data-files", "poligonos_edos_mx.json"),
        mimetype="application/geo+json",
        max_age=86400
    )
    response.headers["Access-Control-Allow-Origin"] = "*"
    return response

# @app.route("/api/poligonos-edos")
# def poligonos_edos():
#     response = send_file(
#         os.path.join(app.root_path, "static/data-files", "poligonos_edos_mx.json"),
#         mimetype="application/geo+json",
#         max_age=0
#     )
#     response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
#     response.headers["Access-Control-Allow-Origin"] = "*"
#     return response


@app.route("/file/download/<path:filename>")
def download_file(filename):
    file_path = os.path.join(app.root_path, "static/data-files", filename)
    if not os.path.isfile(file_path):
        abort(404)
    return send_file(
        file_path,
        as_attachment=True
    )


@app.errorhandler(404)
def page_not_found(error):
    return render_template("404.html"), 404


if __name__ == "__main__":
    app.run(debug=True, threaded=True)
