#!/usr/bin/env python

"""
Module is a copy/paste of https://github.com/mlaradji/task-relative-recur.git
Difference is, we'll execute completeRecurDue and completeRecurWait as strings.

Usage example:
    task add 'Do the dishes' completeRecurWait:"tomorrow +17hours" completeRecurDue:"tomorrow +1day"

"""

import json
import sys
import subprocess
import uuid
import os
import tempfile
import time

TIME_FORMAT = "%Y%m%dT%H%M%SZ"
UDA_DUE = "completeRecurDue"
UDA_WAIT = "completeRecurWait"

env = os.environ.copy()

# Hand back duration format parsing to task warrior
def calc(statement):
    calc = subprocess.Popen(
        ["task", "rc.verbose=nothing", "rc.date.iso=yes", "calc", statement],
        stdout=subprocess.PIPE,
        env=env,
    )
    out, err = calc.communicate()
    # Workaround for TW-1254 (https://bug.tasktools.org/browse/TW-1254)
    return out.decode("utf-8")


# Parse the modified task
original = json.loads(sys.stdin.readline())
modified = sys.stdin.readline()

# Return the unmodified modified task, so it is actually changed
print(modified)
modified = json.loads(modified)

# Has a task with UDA been marked as completed?
if (
    (UDA_DUE in original or UDA_WAIT in original)
    and original["status"] != "completed"
    and modified["status"] == "completed"
):
    del original["modified"]
    if "start" in original:
        del original["start"]
    if UDA_DUE in original:
        original["due"] = calc(original[UDA_DUE])
    if UDA_WAIT in original:
        original["wait"] = calc(original[UDA_WAIT])
        original["status"] = "waiting"
    else:
        original["status"] = "pending"
    print("Created follow-up task")
    original["entry"] = modified["end"]
    original["uuid"] = str(uuid.uuid4())

    # Wait for taskwarrior to finish, so we can safely `task import` the new
    #   task.
    sys.stdout.flush()
    task_pid = os.getppid()
    if 0 < os.fork():
        sys.exit(0)
    else:
        # Taskwarrior also waits for stdout to close
        try:
            os.close(sys.stdout.fileno())
        except OSError:
            pass  # Thrown because of closing stdout. Don't worry, that's fine.

        # Wait for taskwarrior to finish
        # while os.path.exists("/proc/%s" % str(task_pid)):
        time.sleep(1)

        # Import the follow-up task
        with tempfile.NamedTemporaryFile(mode="wt") as new_task:
            new_task.write(json.dumps(original))
            new_task.flush()
            add = subprocess.Popen(
                ["task", "rc.verbose=nothing", "import", new_task.name],
                env=env,
            )
            add.communicate()

