import logging
import os
from urllib.parse import urlparse

import requests

from llama_cpp import Llama
from logdetective.constants import PROMPT_TEMPLATE


LOG = logging.getLogger("logdetective")


def chunk_continues(text: str, index: int) -> bool:
    """Set of heuristics for determining whether or not
    does the current chunk of log text continue on next line.
    """
    conditionals = [
        lambda i, string: string[i + 1].isspace(),
        lambda i, string: string[i - 1] == "\\"
    ]

    for c in conditionals:
        y = c(index, text)
        if y:
            return True

    return False


def get_chunks(text: str):
    """Split log into chunks according to heuristic
    based on whitespace and backslash presence.
    """
    text_len = len(text)
    i = 0
    chunk = ""
    while i < text_len:
        chunk += text[i]
        if text[i] == '\n':
            if i + 1 < text_len and chunk_continues(text, i):
                i += 1
                continue
            yield chunk
            chunk = ""
        i += 1


def initialize_model(model_pth: str, filename_suffix: str = ".gguf", verbose: bool = False) -> Llama:
    """Initialize Llama class for inference.
    Args:
        model_pth (str): path to gguf model file or Hugging Face name
        filename_suffix (str): suffix of the model file name to be pulled from Hugging Face
        verbose (bool): level of verbosity for llamacpp
    """
    if os.path.isfile(model_pth):
        model = Llama(
            model_path=model_pth,
            n_ctx=0,  # Maximum context for the model
            verbose=verbose)
    else:
        model = Llama.from_pretrained(
            model_pth,
            f"*{filename_suffix}",
            n_ctx=0,  # Maximum context for the model
            verbose=verbose)

    return model


def process_log(log: str, model: Llama) -> str:
    """
    Processes a given log using the provided language model and returns its summary.

    Args:
        log (str): The input log to be processed.
        model (Llama): The language model used for processing the log.

    Returns:
        str: The summary of the given log generated by the language model.
    """
    return model(PROMPT_TEMPLATE.format(log), max_tokens=0)["choices"][0]["text"]

def retrieve_log_content(log_path: str) -> str:
    """Get content of the file on the log_path path."""
    parsed_url = urlparse(log_path)
    log = ""

    if not parsed_url.scheme:
        if not os.path.exists(log_path):
            raise ValueError(f"Local log {log_path} doesn't exist!")

        with open(log_path, "rt") as f:
            log = f.read()

    else:
        log = requests.get(log_path, timeout=60).text

    return log
