#!/usr/bin/python3
# -*- python -*-
"""Collect helpers hook data into a single json file"""

import argparse
import json
import os
import sys
import logging
import tempfile
from pathlib import Path

import xdg.BaseDirectory

HOOK_EXT = ".json"

logging.basicConfig(level=logging.INFO)


def collect_helpers(helpers_data_path, hooks_path):
    if not hooks_path.is_dir():
        logging.warning(
            f"failed to collect helpers: hooks directory {hooks_path} "
            f"does not exist"
        )
        return {}

    helpers_data = {}
    for hook_file in hooks_path.iterdir():
        if not hook_file.suffix == HOOK_EXT:
            continue

        logging.debug(f"parsing hook file {hook_file}...")
        try:
            with hook_file.open() as fd:
                data = json.load(fd)
        except (os.Error, json.JSONDecodeError) as e:
            logging.warning(f"failed to load hook file {hook_full_path}: {e}")
            continue

        helper_id = hook_file.stem
        exec_path = data["exec"]
        if exec_path != "":
            exec_path = hook_file.resolve().parent / exec_path
        app_id = data.get("app_id", None)
        if app_id is None:
            # no app_id, use the package name from the helper_id
            app_id = helper_id.split("_")[0]
        elif app_id.count("_") >= 3:
            # remove the version from the app_id
            app_id = app_id.rsplit("_", 1)[0]
        helpers_data[app_id] = {"exec": str(exec_path), "helper_id": helper_id}

    return helpers_data

def build_helper_db(helpers_data_path, hooks_path):
    logging.debug(f"building helper database...")
    helpers_data = collect_helpers(helpers_data_path, hooks_path)

    # write the collected data to a temp file and rename the original once
    # everything is on disk
    tmp = tempfile.NamedTemporaryFile(
        mode="w",
        dir=Path(helpers_data_path).parent,
        prefix=".helpers_data_",
        delete=False
    )
    tmp_path = Path(tmp.name)
    try:
        with tmp:
            json.dump(helpers_data, tmp)
            tmp_path = Path(tmp.name)
        tmp_path.rename(helpers_data_path)
    except OSError as e:
        logging.warning(f"failed to save helper database: {e}")
        return 1
    finally:
        tmp_path.unlink(missing_ok=True)
    logging.debug(f"saved herlper database {helpers_data_path}")
    return 0


if __name__ == "__main__":
    xdg_data_home = xdg.BaseDirectory.xdg_data_home

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("-D", "--debug",
                        help="Enable debug logging",
                        action="store_true",
                        default=False)
    parser.add_argument("-d", "--data-home",
                        help="The Path to the (xdg) data home",
                        default=xdg_data_home)
    args = parser.parse_args()
    if args.debug:
        logging.getLogger().setLevel(logging.DEBUG)

    xdg_data_home = Path(args.data_home)
    helpers_data_path = (
        xdg_data_home / "lomiri-push-service" / "helpers_data.json"
    )
    hooks_path = xdg_data_home / "lomiri-push-service" / "helpers"
    sys.exit(build_helper_db(helpers_data_path, hooks_path))
