"""
Template for defence model
"""

import logging.config
import yaml
import requests
import time
import random
import sys
from fastapi import FastAPI, HTTPException, Request
from pydantic import BaseModel
import os


##########################################################
######### Load any required ENVIRONMENT variables ########
##########################################################
# Environment Variables for victim model URL
GCSS_SERVER = os.getenv("GCSS_SERVER")

# TODO: (Optional) Participant can add any environment variables
pass


##########################################################
# Load Logger's Configuration for the Defense Model App ##
##########################################################
# All logs needs to be sent to sys.stdout or sys.stderr
# TODO:(Optional) Participant can decide logging configuration & use logger.info/error/debug()
# TODO:(Optional) Participant can also opt for sys.stdout.write() or sys.stderr.write()

with open("./logging.yaml", "rt") as f:
    config = yaml.safe_load(f.read())

# Configure the logging module with the config file
logging.config.dictConfig(config)
logger = logging.getLogger("dev_app_logger")

####################################################################################
# This is the post request structure from the client server to defense model server#
####################################################################################
# For defense model
class BasicChatRequest(BaseModel):
    model: int
    message: str


#############################
# Start Defense Model App()##
#############################
app = FastAPI()


@app.on_event("startup")
async def startup_event():
    """Start up defense model fastapi"""
    # Check for GPU availability and names
    logger.info(f"Number of GPUs available: Not NEEDED FOR RANDOM")

    # TODO: (Optional) Load any applicable DEFENCE models if needed
    pass

    logger.info(f"Application started successfully")


############################################
# API Implementations & Helper Function/s ##
############################################
@app.get("/")
async def read_root():
    logger.info("Root endpoint called")
    return {"message": "Hello! This is the RANDOM defense model server"}


# Helper Function to forward request to Victim LLM
async def post_victim_model(model, message):
    """Post to start process"""
    try:
        request = {"model": model, "message": message}
        response = requests.post(GCSS_SERVER + "/chat/respondTo", json=request)

        return response.json()
    except Exception as e:
        return {
            "response": {
                "success": False,
                "message": {"role": "assistant", "content": str(e)},
            }
        }


############################################
################ TEMPLATE ##################
############################################
@app.post("/chat/respondTo", tags=["RandomGuard"])
async def response_from_defense_model(input_data: BasicChatRequest):
    """
    Defense model methodology.
    1. If the input_data.message is "benign", it needs to be forwarded to the Victim-LLM.
       Failure to do, will result in a lower BPR (Benign-Passing Rate)
    2. If the input_data.message is "not benign", participant can choose not to forward
       to the Victim-LLM and craft your own "response["message"]["content"].
    """

    # Get message from Client
    prompt = input_data.message

    # TODO: (Optional) Evaluate input "message"
    pass

    # Forward prompt to Victim Model
    success = False
    while not success:
        response = await post_victim_model(
            model=input_data.model, message=prompt
        )

        try:
            # Check whether succesful got response
            success = response["response"]["success"]
        except:
            success = False

    # TODO: (Optional) Evaluate response["message"]["content"]?
    pass

    # TODO: (Optional) Change the response["message"]["content"] depending on whether its benign/not?
    pass

    # Return the response from the Victim Model to the Client
    return response