/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include <string.h>

#include "log.h"
#include "parameters.h"
#include "activity.h"
#include "async_handle.h"
#include "async_alarm.h"
#include "async_wait.h"

typedef enum {
  ACT_STOPPED,
  ACT_PREPARED,
  ACT_SCHEDULED,
  ACT_STARTED,

  ACT_PREPARING,
  ACT_PREPARING_STOP,

  ACT_STARTING,
  ACT_STARTING_STOP,
  ACT_STARTING_RESTART,

  ACT_STOPPING,
  ACT_STOPPING_START
} ActivityState;

typedef struct {
  const char *name;
} ActivityStateDescriptor;

static const ActivityStateDescriptor activityStateDescriptors[] = {
  [ACT_STOPPED] = {
    .name = "stopped"
  },

  [ACT_PREPARED] = {
    .name = "prepared"
  },

  [ACT_SCHEDULED] = {
    .name = "scheduled"
  },

  [ACT_STARTED] = {
    .name = "started"
  },

  [ACT_PREPARING] = {
    .name = "preparing"
  },

  [ACT_PREPARING_STOP] = {
    .name = "preparing+stop"
  },

  [ACT_STARTING] = {
    .name = "starting"
  },

  [ACT_STARTING_STOP] = {
    .name = "starting+stop"
  },

  [ACT_STARTING_RESTART] = {
    .name = "starting+restart"
  },

  [ACT_STOPPING] = {
    .name = "stopping"
  },

  [ACT_STOPPING_START] = {
    .name = "stopping+start"
  },
};

struct ActivityObjectStruct {
  const ActivityMethods *methods;
  void *data;

  ActivityState state;
  AsyncHandle startAlarm;
};

static const char *
getActivityStateName (ActivityState state) {
  if (state < ARRAY_COUNT(activityStateDescriptors)) {
    const char *name = activityStateDescriptors[state].name;

    if (name && *name) return name;
  }

  return "unknown";
}

static void
logUnexpectedActivityState (ActivityObject *activity, const char *action) {
  ActivityState state = activity->state;

  logMessage(LOG_WARNING, "unexpected activity state: %s: %s: %u[%s]",
             activity->methods->activityName, action, state, getActivityStateName(state));
}

static void
setActivityState (ActivityObject *activity, ActivityState state) {
  logMessage(LOG_DEBUG, "activity state change: %s: %u[%s]",
             activity->methods->activityName, state, getActivityStateName(state));

  activity->state = state;
}

static void
logActivityActionRequest (ActivityObject *activity, const char *action) {
  logMessage(LOG_DEBUG, "activity action request: %s: %s",
             activity->methods->activityName, action);
}

static void
logActivityActionFailed (ActivityObject *activity, const char *action) {
  logMessage(LOG_DEBUG, "activity action failed: %s: %s",
             activity->methods->activityName, action);
}

static void
logActivityActionTimeout (ActivityObject *activity, const char *action) {
  logMessage(LOG_DEBUG, "activity action timeout: %s: %s",
             activity->methods->activityName, action);
}

static void
cancelActivityStartAlarm (ActivityObject *activity) {
  asyncCancelRequest(activity->startAlarm);
  activity->startAlarm = NULL;
}

ASYNC_ALARM_CALLBACK(handleActivityStartAlarm) {
  ActivityObject *activity = parameters->data;
  ActivityStartMethod *start = activity->methods->start;
  ActivityState oldState = activity->state;
  int started;
  ActivityState newState;

  setActivityState(activity, ACT_STARTING);
  started = !start || start(activity->data);

  if (started) {
    cancelActivityStartAlarm(activity);
  } else {
    logActivityActionFailed(activity, "start");
  }

  newState = activity->state;
  setActivityState(activity, (started? ACT_STARTED: oldState));

  if (newState == ACT_STARTING_STOP) {
    stopActivity(activity);
  } else if (newState == ACT_STARTING_RESTART) {
    stopActivity(activity);
    startActivity(activity);
  } else if (newState != ACT_STARTING) {
    logUnexpectedActivityState(activity, "starting");
  }
}

static int
prepareActivity (ActivityObject *activity) {
  ActivityPrepareMethod *prepare = activity->methods->prepare;
  ActivityState oldState = activity->state;

  if (!prepare) {
    setActivityState(activity, ACT_PREPARED);
    return 1;
  }

  setActivityState(activity, ACT_PREPARING);

  if (!prepare(activity->data)) {
    setActivityState(activity, oldState);
    return 0;
  }

  if (activity->state == ACT_PREPARING) {
    setActivityState(activity, ACT_PREPARED);
    return 1;
  }

  if (activity->state == ACT_PREPARING_STOP) {
    setActivityState(activity, ACT_STOPPED);
    return 0;
  }

  logUnexpectedActivityState(activity, "preparing");
  return 0;
}

static int
scheduleActivity (ActivityObject *activity) {
  if (asyncNewRelativeAlarm(&activity->startAlarm, 0, handleActivityStartAlarm, activity)) {
    if (asyncResetAlarmInterval(activity->startAlarm, activity->methods->retryInterval)) {
      setActivityState(activity, ACT_SCHEDULED);
      return 1;
    }

    cancelActivityStartAlarm(activity);
  }

  return 0;
}

void
startActivity (ActivityObject *activity) {
  logActivityActionRequest(activity, "start");

  while (1) {
    switch (activity->state) {
      case ACT_STOPPED:
        if (prepareActivity(activity)) continue;
        return;

      case ACT_PREPARING_STOP:
        setActivityState(activity, ACT_PREPARING);
        continue;

      case ACT_PREPARED:
        if (scheduleActivity(activity)) continue;
        return;

      case ACT_SCHEDULED:
        asyncResetAlarmIn(activity->startAlarm, 0);
        return;

      case ACT_STARTING_STOP:
        setActivityState(activity, ACT_STARTING_RESTART);
        continue;

      case ACT_STOPPING:
        setActivityState(activity, ACT_STOPPING_START);
        continue;

      case ACT_PREPARING:
      case ACT_STARTING:
      case ACT_STARTING_RESTART:
      case ACT_STARTED:
      case ACT_STOPPING_START:
        return;
    }

    logUnexpectedActivityState(activity, "start");
    break;
  }
}

void
stopActivity (ActivityObject *activity) {
  logActivityActionRequest(activity, "stop");

  while (1) {
    switch (activity->state) {
      case ACT_PREPARING:
        setActivityState(activity, ACT_PREPARING_STOP);
        continue;

      case ACT_PREPARED:
        setActivityState(activity, ACT_STOPPED);
        continue;

      case ACT_SCHEDULED:
        cancelActivityStartAlarm(activity);
        setActivityState(activity, ACT_PREPARED);
        continue;

      case ACT_STARTING:
      case ACT_STARTING_RESTART:
        setActivityState(activity, ACT_STARTING_STOP);
        continue;

      case ACT_STARTED: {
        ActivityStopMethod *stop = activity->methods->stop;

        if (stop) {
          ActivityState newState;

          setActivityState(activity, ACT_STOPPING);
          stop(activity->data);
          newState = activity->state;
          setActivityState(activity, ACT_STOPPED);

          if (newState == ACT_STOPPING_START) {
            startActivity(activity);
          } else if (newState != ACT_STOPPING) {
            logUnexpectedActivityState(activity, "stopping");
          }
        } else {
          setActivityState(activity, ACT_STOPPED);
        }

        return;
      }

      case ACT_STOPPING_START:
        setActivityState(activity, ACT_STOPPING);
        continue;

      case ACT_PREPARING_STOP:
      case ACT_STARTING_STOP:
      case ACT_STOPPING:
      case ACT_STOPPED:
        return;
    }

    logUnexpectedActivityState(activity, "stop");
    break;
  }
}

ActivityObject *
newActivity (const ActivityMethods *methods, void *data) {
  ActivityObject *activity;

  if ((activity = malloc(sizeof(*activity)))) {
    memset(activity, 0, sizeof(*activity));

    activity->methods = methods;
    activity->data = data;

    activity->state = ACT_STOPPED;
    activity->startAlarm = NULL;

    return activity;
  } else {
    logMallocError();
  }

  return NULL;
}

void
destroyActivity (ActivityObject *activity) {
  stopActivity(activity);
  awaitActivityStopped(activity);
  free(activity);
}

int
isActivityStarted (const ActivityObject *activity) {
  return activity->state == ACT_STARTED;
}

int
isActivityStopped (const ActivityObject *activity) {
  return activity->state == ACT_STOPPED;
}

ASYNC_CONDITION_TESTER(testActivityStarted) {
  const ActivityObject *activity = data;

  return isActivityStarted(activity);
}

int
awaitActivityStarted (ActivityObject *activity) {
  int timeout = activity->methods->startTimeout;

  if (!timeout) timeout = DEFAULT_ACTIVITY_START_TIMEOUT;
  if (asyncAwaitCondition(timeout, testActivityStarted, activity)) return 1;

  logActivityActionTimeout(activity, "start");
  return 0;
}

ASYNC_CONDITION_TESTER(testActivityStopped) {
  const ActivityObject *activity = data;

  return isActivityStopped(activity);
}

int
awaitActivityStopped (ActivityObject *activity) {
  int timeout = activity->methods->stopTimeout;

  if (!timeout) timeout = DEFAULT_ACTIVITY_STOP_TIMEOUT;
  if (asyncAwaitCondition(timeout, testActivityStopped, activity)) return 1;

  logActivityActionTimeout(activity, "stop");
  return 0;
}
