"""
Do not edit this file
This is the file that will be used to test your model
"""
import os
import json
from typing import Callable, Coroutine, Mapping
import requests

from .utils import make_file, clean_files

class TestResults:
    """Results of testing."""
    def __init__(self, metrics: dict[str, float], files: Mapping[str, bytes | str], predictions: []):
        self.metrics = metrics
        self.files = files
        self.predictions = predictions

async def test(
    main: Callable[..., Coroutine[None, None, TestResults]],
    result_id: str,
    api_url: str,
    user_token: str,
    **kwargs, 
):
    """
    Train a model
    This function will provide the dataset path, parameters and result_id
    and will return the results of training.
    """
    try:
        test_result = await main(result_id=result_id, **kwargs)

        # Stringify metrics
        metrics = json.dumps(test_result.metrics)
        predictions = str(test_result.predictions)
        print(predictions)
        print(list(predictions))
        data = {
            "result_id": result_id,
            "metrics": metrics,
            "predictions": predictions,
            "pkg_name": "pymlab.test",
        }

        response = requests.post(api_url, data=data, files=test_result.files,timeout=120, verify=False, headers={"Authorization":f"Bearer {user_token}"})

        if response.status_code == 200:
            # delete files
            clean_files(result_id)
        else:
            raise requests.HTTPError(f"Error uploading results. Status code: {response.status_code}, error: {response.text}")

    except Exception as e:
        file_path = make_file(result_id, "error.txt", str(e))
        with open(file_path, "rb") as f:
            error_file = f.read()
        req_files = {
            "error.txt": error_file,
        }
        requests.post(api_url+f"?error={True}", data={"result_id": result_id, "error": str(e)}, files=req_files, timeout=120, verify=False, headers={"Authorization":f"Bearer {user_token}"})
