from datetime import datetime
from typing import Optional

from anyscale.api import get_anyscale_api_client, get_api_client
from anyscale.cli_logger import _CliLogger
from anyscale.client.openapi_client.api.default_api import DefaultApi
from anyscale.cloud import get_cloud_id_and_name, get_last_used_cloud
from anyscale.sdk.anyscale_client import (
    ComputeTemplate,
    ComputeTemplateConfig,
    ComputeTemplateQuery,
    CreateComputeTemplate,
)
from anyscale.utils.cloud_utils import get_organization_default_cloud


log = _CliLogger()


def get_default_cluster_compute(
    cloud_name: Optional[str],
    project_id: Optional[str],
    api_client: Optional[DefaultApi] = None,
    anyscale_api_client: Optional[DefaultApi] = None,
) -> ComputeTemplate:
    if api_client is None:
        api_client = get_api_client()
    if anyscale_api_client is None:
        anyscale_api_client = get_anyscale_api_client()

    if cloud_name is None:
        default_cloud_name = get_organization_default_cloud(api_client)
        if default_cloud_name:
            cloud_name = default_cloud_name
        else:
            cloud_name = get_last_used_cloud(project_id, anyscale_api_client)

    cloud_id, _ = get_cloud_id_and_name(api_client, cloud_name=cloud_name)
    config_object = anyscale_api_client.get_default_compute_config(cloud_id).result
    compute_template = register_compute_template(config_object)
    return compute_template


def get_cluster_compute_from_name(
    cluster_compute_name: str, api_client: Optional[DefaultApi] = None,
) -> ComputeTemplate:
    if api_client is None:
        api_client = get_api_client()
    cluster_computes = api_client.search_compute_templates_api_v2_compute_templates_search_post(
        ComputeTemplateQuery(
            orgwide=True, name={"equals": cluster_compute_name}, include_anonymous=True,
        )
    ).results

    if len(cluster_computes) == 0:
        raise ValueError(
            f"The cluster compute template {cluster_compute_name}" " is not registered."
        )
    return cluster_computes[0]


def register_compute_template(
    config_object: ComputeTemplateConfig, api_client: Optional[DefaultApi] = None,
) -> ComputeTemplate:
    """
    Register compute template with a default name and return the compute template id."""
    if api_client is None:
        api_client = get_api_client()
    created_template = api_client.create_compute_template_api_v2_compute_templates_post(
        create_compute_template=CreateComputeTemplate(
            name="cli-autogenerated-config-{}".format(datetime.now().isoformat()),
            config=config_object,
            anonymous=True,
        )
    ).result
    return created_template
