import json
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen


SDK_VERSION = '1.0.0'


class EntropyClient:
    """Private TRITROIA adapter for the isolated Entropy Core."""

    def __init__(self, base_url, timeout=3):
        self.base_url = base_url.rstrip('/')
        self.timeout = timeout

    def issue(self, context=None):
        request = Request(
            f'{self.base_url}/v1/entropy',
            data=json.dumps({'context': context or {}}, ensure_ascii=True).encode('utf-8'),
            headers={'Accept': 'application/json', 'Content-Type': 'application/json', 'X-Entropy-SDK-Version': SDK_VERSION},
            method='POST',
        )
        try:
            with urlopen(request, timeout=self.timeout) as response:
                payload = json.loads(response.read().decode('utf-8'))
        except (HTTPError, URLError, TimeoutError, OSError, ValueError, json.JSONDecodeError) as error:
            raise RuntimeError(f'entropy_core_unavailable: {error}') from error
        if not isinstance(payload, dict) or not payload.get('token'):
            raise RuntimeError('entropy_core_invalid_response')
        return payload

    def health(self):
        try:
            with urlopen(f'{self.base_url}/health', timeout=self.timeout) as response:
                return json.loads(response.read().decode('utf-8'))
        except (HTTPError, URLError, TimeoutError, OSError, ValueError, json.JSONDecodeError) as error:
            raise RuntimeError(f'entropy_core_unavailable: {error}') from error

    def status(self):
        try:
            return {'connected': True, 'url': self.base_url, 'health': self.health()}
        except RuntimeError as error:
            return {'connected': False, 'url': self.base_url, 'error': str(error)}
