from __future__ import print_function
import json
import logging
import os
try:
    from urllib.parse import urlencode
    from urllib.request import Request, urlopen
except ImportError:
    from urllib import urlencode
    from urllib2 import Request, urlopen
from .util import atomic_copy_if_changed, atomic_write_if_changed, atomic_write, event_matches, isoformat, safe_text

LOG = logging.getLogger(__name__)


def update_supermon(config, alerts):
    if not config.get("enabled", True):
        return
    path = config.get("warnings_path", "/tmp/AUTOSKY/warnings.txt")
    titles = []
    for alert in sorted(alerts.values(), key=lambda item: (item.event, item.area_desc)):
        label = alert.event
        if alert.matched_areas:
            label += " - " + ", ".join(alert.matched_areas)
        titles.append(label)
    atomic_write_if_changed(path, "\n".join(titles) + ("\n" if titles else ""))


def update_tail(config, audio_renderer, alerts, sentence):
    if not config.get("enabled", True):
        return None
    include = config.get("include_events") or []
    exclude = config.get("exclude_events") or []
    selected = [a for a in alerts.values() if (not include or event_matches(a.event, include)) and not event_matches(a.event, exclude)]
    target_base = config.get("path")
    target = target_base + ".ulaw"
    if not selected:
        for stale in (target, target_base + ".txt"):
            try:
                os.unlink(stale)
            except OSError:
                pass
        return None
    generated_base = audio_renderer.render(
        sentence(selected),
        "tail-message",
        prefix_files=config.get("prefix_audio") or [],
        suffix_files=config.get("suffix_audio") or [],
    )
    if os.path.exists(generated_base + ".ulaw"):
        atomic_copy_if_changed(generated_base + ".ulaw", target)
        return target_base
    # Dry-run/audio-disabled mode still exposes the generated wording for testing.
    if os.path.exists(generated_base + ".txt"):
        atomic_copy_if_changed(generated_base + ".txt", target_base + ".txt")
    return target_base


def switch_courtesy_tones(config, alerts, forced=None):
    if not config.get("enabled", False):
        return None
    weather = bool(alerts)
    patterns = config.get("trigger_events") or []
    if patterns:
        weather = any(event_matches(a.event, patterns) for a in alerts.values())
    if forced in ("normal", "weather"):
        weather = forced == "weather"
    mode = "weather" if weather else "normal"
    for target, pair in (config.get("files") or {}).items():
        source = (pair or {}).get(mode)
        if not source:
            continue
        if not os.path.exists(source):
            LOG.error("Courtesy tone source does not exist: %s", source)
            continue
        atomic_copy_if_changed(source, target)
    return mode


def switch_id(config, alerts, forced=None):
    if not config.get("enabled", False):
        return None
    weather = bool(alerts)
    patterns = config.get("trigger_events") or []
    if patterns:
        weather = any(event_matches(a.event, patterns) for a in alerts.values())
    if forced in ("normal", "weather"):
        weather = forced == "weather"
    mode = "weather" if weather else "normal"
    source = config.get(mode)
    target = config.get("target")
    if source and target:
        if not os.path.exists(source):
            raise RuntimeError("ID source does not exist: %s" % source)
        atomic_copy_if_changed(source, target)
    return mode


def send_pushover(config, title, message):
    if not config.get("enabled", False):
        return
    data = urlencode({
        "token": config.get("api_token", ""),
        "user": config.get("user_key", ""),
        "title": safe_text(title, 250),
        "message": safe_text(message, 1024),
    }).encode("utf-8")
    request = Request("https://api.pushover.net/1/messages.json", data=data)
    urlopen(request, timeout=15).read()


def write_status(runtime_dir, payload):
    payload = dict(payload)
    payload["generated_at"] = isoformat()
    atomic_write(os.path.join(runtime_dir, "status.json"), json.dumps(payload, sort_keys=True, indent=2))
