"""
Flask integration example for Kilit.

This example shows how to use Kilit to manage encrypted secrets
in a Flask application.
"""

from flask import Flask
from kilit import Credentials

# Initialize Flask app
app = Flask(__name__)

# Load credentials
creds = Credentials("config/credentials.json.enc")


# Configuration from encrypted credentials
# =========================================

# Flask secret key
app.config["SECRET_KEY"] = creds.require("flask.secret_key")

# Database configuration
app.config["SQLALCHEMY_DATABASE_URI"] = (
    f"postgresql://{creds.require('database.user')}:"
    f"{creds.require('database.password')}@"
    f"{creds.get('database.host', 'localhost')}:"
    f"{creds.get('database.port', 5432)}/"
    f"{creds.get('database.name', 'myapp_db')}"
)
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

# Redis configuration
app.config["REDIS_URL"] = creds.get("redis.url", "redis://localhost:6379/0")

# Email configuration
app.config["MAIL_SERVER"] = creds.get("email.host", "smtp.gmail.com")
app.config["MAIL_PORT"] = creds.get("email.port", 587)
app.config["MAIL_USE_TLS"] = True
app.config["MAIL_USERNAME"] = creds.require("email.user")
app.config["MAIL_PASSWORD"] = creds.require("email.password")

# Third-party API keys
app.config["STRIPE_SECRET_KEY"] = creds.require("stripe.secret_key")
app.config["STRIPE_PUBLISHABLE_KEY"] = creds.require("stripe.publishable_key")

# JWT configuration
app.config["JWT_SECRET_KEY"] = creds.require("jwt.secret_key")
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = creds.get("jwt.access_token_expires", 3600)


# Using credentials in routes
# ============================

@app.route("/")
def index():
    return "Hello, World!"


@app.route("/api/config")
def api_config():
    """Example: Expose non-sensitive config to frontend."""
    return {
        "stripe_publishable_key": app.config["STRIPE_PUBLISHABLE_KEY"],
        "environment": creds.get("app.environment", "production"),
    }


# Using credentials with extensions
# ==================================

from flask_sqlalchemy import SQLAlchemy
from flask_mail import Mail
from flask_redis import FlaskRedis

db = SQLAlchemy(app)
mail = Mail(app)
redis_client = FlaskRedis(app)


# Factory pattern example
# ========================

def create_app(config_name="production"):
    """Application factory pattern with Kilit."""
    app = Flask(__name__)
    
    # Load credentials
    creds = Credentials("config/credentials.json.enc")
    
    # Load config based on environment
    app.config["SECRET_KEY"] = creds.require("flask.secret_key")
    app.config["SQLALCHEMY_DATABASE_URI"] = creds.require(f"database.{config_name}.url")
    
    # Initialize extensions
    db.init_app(app)
    mail.init_app(app)
    
    return app


# Example credentials.json structure:
# ====================================
"""
{
  "flask": {
    "secret_key": "your-flask-secret-key"
  },
  "database": {
    "user": "myapp_user",
    "password": "super-secret-password",
    "host": "localhost",
    "port": 5432,
    "name": "myapp_db",
    "production": {
      "url": "postgresql://user:pass@prod-db.example.com/myapp"
    },
    "staging": {
      "url": "postgresql://user:pass@staging-db.example.com/myapp"
    }
  },
  "redis": {
    "url": "redis://localhost:6379/0"
  },
  "email": {
    "host": "smtp.gmail.com",
    "port": 587,
    "user": "noreply@example.com",
    "password": "email-password"
  },
  "stripe": {
    "secret_key": "sk_live_...",
    "publishable_key": "pk_live_..."
  },
  "jwt": {
    "secret_key": "your-jwt-secret-key",
    "access_token_expires": 3600
  },
  "app": {
    "environment": "production"
  }
}
"""


# Setup instructions:
# ===================
"""
1. Initialize encrypted credentials:
   $ kilit init --path config/credentials.json.enc

2. Edit credentials:
   $ kilit edit --path config/credentials.json.enc

3. Add to .gitignore:
   config/master.key

4. Run Flask app:
   $ export KILIT_MASTER_KEY="your-master-key"
   $ flask run

5. For development, use local master key file:
   $ flask run
   (reads from config/master.key automatically)
"""


if __name__ == "__main__":
    app.run(debug=creds.get("app.debug", False))
