"""Explicit Pushover adapter; API acceptance is not proof of device delivery."""
import argparse
import json
import os
from pathlib import Path
import stat
import urllib.error
import urllib.parse
import urllib.request


def load_json(raw):
    return json.loads(raw)


class NoRedirect(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, *args, **kwargs):
        return None


def push(message, credentials):
    if not credentials or not credentials.get('app_token') or not credentials.get('user_token'):
        return 'NOT_CONFIGURED'
    if len(message) > 1024:
        return 'PERMANENT_REJECTION'
    body = urllib.parse.urlencode({'token': credentials['app_token'], 'user': credentials['user_token'], 'message': message, 'priority': 1, 'sound': 'siren'}).encode()
    req = urllib.request.Request('https://api.pushover.net/1/messages.json', data=body, method='POST')
    try:
        with urllib.request.build_opener(NoRedirect).open(req, timeout=8) as response:
            data = load_json(response.read(16385))
            if response.status == 200 and isinstance(data, dict) and type(data.get('status')) is int and data['status'] == 1:
                return 'API_ACCEPTED'
            return 'PERMANENT_REJECTION'
    except urllib.error.HTTPError as e:
        if e.code == 429:
            return 'RETRY'
        if 400 <= e.code < 500:
            return 'PERMANENT_REJECTION'
        return 'UNKNOWN'
    except Exception:
        # Server may have accepted before timeout: never blindly retransmit.
        return 'UNKNOWN'


def credentials_from_file(path):
    path=Path(path)
    if not path.exists():return None
    st=path.stat()
    if path.is_symlink() or not stat.S_ISREG(st.st_mode) or st.st_uid!=os.getuid() or st.st_mode & 0o077:
        raise ValueError('Notification credentials must be privately owned (600 or 400)')
    values={}
    if path.suffix=='.json':
        data=json.loads(path.read_text())
        if not isinstance(data,dict):raise ValueError('Invalid credential structure')
        values={'app_token':data.get('app_token'),'user_token':data.get('user_token')}
    else:
        for line in path.read_text().splitlines():
            line=line.strip()
            if not line or line.startswith('#'):continue
            if line.startswith('export '):line=line[7:].strip()
            if '=' not in line:continue
            key,value=line.split('=',1);key=key.strip();value=value.strip()
            mapping={'NOTIFIER_APP_TOKEN':'app_token','NOTIFIER_USER_TOKEN':'user_token'}
            if key not in mapping:continue
            if mapping[key] in values:raise ValueError('Duplicate notification credential')
            if len(value)>=2 and value[0]==value[-1] and value[0] in '\"\'':value=value[1:-1]
            values[mapping[key]]=value
    for key in ('app_token','user_token'):
        value=values.get(key)
        if value is not None and not isinstance(value,str):raise ValueError('Invalid notification credential type')
    return values


class ConsigliereTelemetryNotifier:
    def __init__(self,credentials_path='/Users/bpa/ForesixaQuant/notification_credentials.json',*,transport=None):
        self.credentials=credentials_from_file(credentials_path)
        self.transport=transport or push
        self.last_result={'status':'NOT_SENT'}

    def dispatch_message(self,message):
        if not isinstance(message,str) or not message.strip() or len(message)>1024:
            self.last_result={'status':'INVALID_MESSAGE'};return False
        if not self.credentials or not self.credentials.get('app_token') or not self.credentials.get('user_token'):
            self.last_result={'status':'NOT_CONFIGURED'};return False
        try:result=self.transport(message,self.credentials)
        except Exception:result='UNKNOWN'
        if result not in ('API_ACCEPTED','NOT_CONFIGURED','RETRY','PERMANENT_REJECTION','UNKNOWN'):result='UNKNOWN'
        self.last_result={'status':result,'device_delivery':'UNVERIFIED'}
        return result=='API_ACCEPTED'

    def dispatch_emergency_triage_sms(self,project_name,horizontal_vertical,verified_action,*,execution_status='PENDING_EXECUTION'):
        """Compatibility method: sends push, not SMS; status is caller-supplied."""
        if execution_status not in ('PENDING_EXECUTION','STAGED','DEPLOYED','VERIFIED_CLEARED','REPORTED_CLEARED','FAILED','UNKNOWN'):
            raise ValueError('Unsupported execution status')
        return self.dispatch_message(f'QZOTIC: {project_name} ({horizontal_vertical}); directive {verified_action}; reported status {execution_status}. Business outcome not established by this notification.')


if __name__=='__main__':
    p=argparse.ArgumentParser();p.add_argument('--credentials',default='/Users/bpa/ForesixaQuant/notification_credentials.json');p.add_argument('--send',action='store_true');p.add_argument('--message');args=p.parse_args()
    if not args.send:
        print(json.dumps({'status':'DRY_RUN','sent':False,'notice':'Use --send with --message only for an authorized notification.'}))
    else:
        notifier=ConsigliereTelemetryNotifier(args.credentials)
        ok=notifier.dispatch_message(args.message)
        print(json.dumps(notifier.last_result));raise SystemExit(0 if ok else 2)
