from __future__ import annotations

SENTINEL: int = -1
MAX_RETRIES: int = 3
DEFAULT_TIMEOUT: float = 30.0
MAX_POOL_SIZE: int = 64
CHUNK_SIZE: int = 256
BASE_SCORE: int = 100
BACKOFF_MS: int = 100
HTTP_OK: int = 200
HTTP_NOT_FOUND: int = 404
HTTP_SERVER_ERROR: int = 500
HTTP_UNAVAILABLE: int = 503


class CoreError:
    code: int = 0
    message: str = ""

    def is_fatal(self: "CoreError") -> bool:
        return self.code >= HTTP_SERVER_ERROR

    def is_client_error(self: "CoreError") -> bool:
        return 400 <= self.code < HTTP_SERVER_ERROR

    def describe(self: "CoreError") -> str:
        return "code=" + str(self.code) + " " + self.message

    def is_ok(self: "CoreError") -> bool:
        return self.code == 0


class RetryPolicy:
    max_attempts: int = MAX_RETRIES
    backoff_ms: int = BACKOFF_MS
    jitter: bool = False

    def should_retry(self: "RetryPolicy", attempt: int) -> bool:
        return attempt < self.max_attempts

    def delay_ms(self: "RetryPolicy", attempt: int) -> int:
        factor: int = attempt + 1
        return self.backoff_ms * factor

    def total_budget_ms(self: "RetryPolicy") -> int:
        total: int = 0
        idx: int = 0
        while idx < self.max_attempts:
            total = total + self.delay_ms(idx)
            idx = idx + 1
        return total



class ConnectionConfig:
    host: str = "localhost"
    port: int = 8080
    timeout: float = DEFAULT_TIMEOUT
    max_connections: int = MAX_POOL_SIZE
    protocol: str = "http"

    def endpoint_url(self: "ConnectionConfig") -> str:
        return self.protocol + "://" + self.host + ":" + str(self.port)

    def is_local(self: "ConnectionConfig") -> bool:
        return self.host == "localhost"

    def is_secure(self: "ConnectionConfig") -> bool:
        return self.protocol == "https"



DEFAULT_RETRY_POLICY: RetryPolicy = RetryPolicy()
DEFAULT_CONNECTION_CONFIG: ConnectionConfig = ConnectionConfig()
FATAL_ERROR: CoreError = CoreError()
