//===-- libdebugserver.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <errno.h>
#include <getopt.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/types.h>

#include "DNB.h"
#include "DNBLog.h"
#include "DNBTimer.h"
#include "PseudoTerminal.h"
#include "RNBContext.h"
#include "RNBRemote.h"
#include "RNBServices.h"
#include "RNBSocket.h"
#include "SysSignal.h"

//----------------------------------------------------------------------
// Run loop modes which determine which run loop function will be called
//----------------------------------------------------------------------
typedef enum {
  eRNBRunLoopModeInvalid = 0,
  eRNBRunLoopModeGetStartModeFromRemoteProtocol,
  eRNBRunLoopModeInferiorExecuting,
  eRNBRunLoopModeExit
} RNBRunLoopMode;

//----------------------------------------------------------------------
// Global Variables
//----------------------------------------------------------------------
RNBRemoteSP g_remoteSP;
int g_disable_aslr = 0;
int g_isatty = 0;

#define RNBLogSTDOUT(fmt, ...)                                                 \
  do {                                                                         \
    if (g_isatty) {                                                            \
      fprintf(stdout, fmt, ##__VA_ARGS__);                                     \
    } else {                                                                   \
      _DNBLog(0, fmt, ##__VA_ARGS__);                                          \
    }                                                                          \
  } while (0)
#define RNBLogSTDERR(fmt, ...)                                                 \
  do {                                                                         \
    if (g_isatty) {                                                            \
      fprintf(stderr, fmt, ##__VA_ARGS__);                                     \
    } else {                                                                   \
      _DNBLog(0, fmt, ##__VA_ARGS__);                                          \
    }                                                                          \
  } while (0)

//----------------------------------------------------------------------
// Get our program path and arguments from the remote connection.
// We will need to start up the remote connection without a PID, get the
// arguments, wait for the new process to finish launching and hit its
// entry point,  and then return the run loop mode that should come next.
//----------------------------------------------------------------------
RNBRunLoopMode RNBRunLoopGetStartModeFromRemote(RNBRemoteSP &remoteSP) {
  std::string packet;

  if (remoteSP.get() != NULL) {
    RNBRemote *remote = remoteSP.get();
    RNBContext &ctx = remote->Context();
    uint32_t event_mask = RNBContext::event_read_packet_available;

    // Spin waiting to get the A packet.
    while (1) {
      DNBLogThreadedIf(LOG_RNB_MAX,
                       "%s ctx.Events().WaitForSetEvents( 0x%08x ) ...",
                       __FUNCTION__, event_mask);
      nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
      DNBLogThreadedIf(LOG_RNB_MAX,
                       "%s ctx.Events().WaitForSetEvents( 0x%08x ) => 0x%08x",
                       __FUNCTION__, event_mask, set_events);

      if (set_events & RNBContext::event_read_packet_available) {
        rnb_err_t err = rnb_err;
        RNBRemote::PacketEnum type;

        err = remote->HandleReceivedPacket(&type);

        // check if we tried to attach to a process
        if (type == RNBRemote::vattach || type == RNBRemote::vattachwait) {
          if (err == rnb_success)
            return eRNBRunLoopModeInferiorExecuting;
          else {
            RNBLogSTDERR("error: attach failed.");
            return eRNBRunLoopModeExit;
          }
        }

        if (err == rnb_success) {
          DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Got success...", __FUNCTION__);
          continue;
        } else if (err == rnb_not_connected) {
          RNBLogSTDERR("error: connection lost.");
          return eRNBRunLoopModeExit;
        } else {
          // a catch all for any other gdb remote packets that failed
          DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Error getting packet.",
                           __FUNCTION__);
          continue;
        }

        DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
      } else {
        DNBLogThreadedIf(LOG_RNB_MINIMAL,
                         "%s Connection closed before getting \"A\" packet.",
                         __FUNCTION__);
        return eRNBRunLoopModeExit;
      }
    }
  }
  return eRNBRunLoopModeExit;
}

//----------------------------------------------------------------------
// Watch for signals:
// SIGINT: so we can halt our inferior. (disabled for now)
// SIGPIPE: in case our child process dies
//----------------------------------------------------------------------
nub_process_t g_pid;
int g_sigpipe_received = 0;
void signal_handler(int signo) {
  DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (%s)", __FUNCTION__,
                   SysSignal::Name(signo));

  switch (signo) {
  //  case SIGINT:
  //      DNBProcessKill (g_pid, signo);
  //      break;

  case SIGPIPE:
    g_sigpipe_received = 1;
    break;
  }
}

// Return the new run loop mode based off of the current process state
RNBRunLoopMode HandleProcessStateChange(RNBRemoteSP &remote, bool initialize) {
  RNBContext &ctx = remote->Context();
  nub_process_t pid = ctx.ProcessID();

  if (pid == INVALID_NUB_PROCESS) {
    DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s error: pid invalid, exiting...",
                     __FUNCTION__);
    return eRNBRunLoopModeExit;
  }
  nub_state_t pid_state = DNBProcessGetState(pid);

  DNBLogThreadedIf(LOG_RNB_MINIMAL,
                   "%s (&remote, initialize=%i)  pid_state = %s", __FUNCTION__,
                   (int)initialize, DNBStateAsString(pid_state));

  switch (pid_state) {
  case eStateInvalid:
  case eStateUnloaded:
    // Something bad happened
    return eRNBRunLoopModeExit;
    break;

  case eStateAttaching:
  case eStateLaunching:
    return eRNBRunLoopModeInferiorExecuting;

  case eStateSuspended:
  case eStateCrashed:
  case eStateStopped:
    if (!initialize) {
      // Compare the last stop count to our current notion of a stop count
      // to make sure we don't notify more than once for a given stop.
      nub_size_t prev_pid_stop_count = ctx.GetProcessStopCount();
      bool pid_stop_count_changed =
          ctx.SetProcessStopCount(DNBProcessGetStopCount(pid));
      if (pid_stop_count_changed) {
        remote->FlushSTDIO();

        if (ctx.GetProcessStopCount() == 1) {
          DNBLogThreadedIf(
              LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s "
                               "pid_stop_count %zu (old %zu)) Notify??? no, "
                               "first stop...",
              __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
              ctx.GetProcessStopCount(), prev_pid_stop_count);
        } else {

          DNBLogThreadedIf(
              LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s "
                               "pid_stop_count %zu (old %zu)) Notify??? YES!!!",
              __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
              ctx.GetProcessStopCount(), prev_pid_stop_count);
          remote->NotifyThatProcessStopped();
        }
      } else {
        DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  "
                                          "pid_state = %s pid_stop_count %zu "
                                          "(old %zu)) Notify??? skipping...",
                         __FUNCTION__, (int)initialize,
                         DNBStateAsString(pid_state), ctx.GetProcessStopCount(),
                         prev_pid_stop_count);
      }
    }
    return eRNBRunLoopModeInferiorExecuting;

  case eStateStepping:
  case eStateRunning:
    return eRNBRunLoopModeInferiorExecuting;

  case eStateExited:
    remote->HandlePacket_last_signal(NULL);
    return eRNBRunLoopModeExit;
  case eStateDetached:
    return eRNBRunLoopModeExit;
  }

  // Catch all...
  return eRNBRunLoopModeExit;
}
// This function handles the case where our inferior program is stopped and
// we are waiting for gdb remote protocol packets. When a packet occurs that
// makes the inferior run, we need to leave this function with a new state
// as the return code.
RNBRunLoopMode RNBRunLoopInferiorExecuting(RNBRemoteSP &remote) {
  DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
  RNBContext &ctx = remote->Context();

  // Init our mode and set 'is_running' based on the current process state
  RNBRunLoopMode mode = HandleProcessStateChange(remote, true);

  while (ctx.ProcessID() != INVALID_NUB_PROCESS) {

    std::string set_events_str;
    uint32_t event_mask = ctx.NormalEventBits();

    if (!ctx.ProcessStateRunning()) {
      // Clear the stdio bits if we are not running so we don't send any async
      // packets
      event_mask &= ~RNBContext::event_proc_stdio_available;
    }

    // We want to make sure we consume all process state changes and have
    // whomever is notifying us to wait for us to reset the event bit before
    // continuing.
    // ctx.Events().SetResetAckMask (RNBContext::event_proc_state_changed);

    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) ...",
                     __FUNCTION__, event_mask);
    nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",
                     __FUNCTION__, event_mask, set_events,
                     ctx.EventsAsString(set_events, set_events_str));

    if (set_events) {
      if ((set_events & RNBContext::event_proc_thread_exiting) ||
          (set_events & RNBContext::event_proc_stdio_available)) {
        remote->FlushSTDIO();
      }

      if (set_events & RNBContext::event_read_packet_available) {
        // handleReceivedPacket will take care of resetting the
        // event_read_packet_available events when there are no more...
        set_events ^= RNBContext::event_read_packet_available;

        if (ctx.ProcessStateRunning()) {
          if (remote->HandleAsyncPacket() == rnb_not_connected) {
            // TODO: connect again? Exit?
          }
        } else {
          if (remote->HandleReceivedPacket() == rnb_not_connected) {
            // TODO: connect again? Exit?
          }
        }
      }

      if (set_events & RNBContext::event_proc_state_changed) {
        mode = HandleProcessStateChange(remote, false);
        ctx.Events().ResetEvents(RNBContext::event_proc_state_changed);
        set_events ^= RNBContext::event_proc_state_changed;
      }

      if (set_events & RNBContext::event_proc_thread_exiting) {
        mode = eRNBRunLoopModeExit;
      }

      if (set_events & RNBContext::event_read_thread_exiting) {
        // Out remote packet receiving thread exited, exit for now.
        if (ctx.HasValidProcessID()) {
          // TODO: We should add code that will leave the current process
          // in its current state and listen for another connection...
          if (ctx.ProcessStateRunning()) {
            DNBProcessKill(ctx.ProcessID());
          }
        }
        mode = eRNBRunLoopModeExit;
      }
    }

    // Reset all event bits that weren't reset for now...
    if (set_events != 0)
      ctx.Events().ResetEvents(set_events);

    if (mode != eRNBRunLoopModeInferiorExecuting)
      break;
  }

  return mode;
}

void ASLLogCallback(void *baton, uint32_t flags, const char *format,
                    va_list args) {
#if 0
	vprintf(format, args);
#endif
}

extern "C" int debug_server_main(int fd) {
#if 1
  g_isatty = 0;
#else
  g_isatty = ::isatty(STDIN_FILENO);

  DNBLogSetDebug(1);
  DNBLogSetVerbose(1);
  DNBLogSetLogMask(-1);
  DNBLogSetLogCallback(ASLLogCallback, NULL);
#endif

  signal(SIGPIPE, signal_handler);

  g_remoteSP.reset(new RNBRemote);

  RNBRemote *remote = g_remoteSP.get();
  if (remote == NULL) {
    RNBLogSTDERR("error: failed to create a remote connection class\n");
    return -1;
  }

  RNBRunLoopMode mode = eRNBRunLoopModeGetStartModeFromRemoteProtocol;

  while (mode != eRNBRunLoopModeExit) {
    switch (mode) {
    case eRNBRunLoopModeGetStartModeFromRemoteProtocol:
      if (g_remoteSP->Comm().useFD(fd) == rnb_success) {
        RNBLogSTDOUT("Starting remote data thread.\n");
        g_remoteSP->StartReadRemoteDataThread();

        RNBLogSTDOUT("Waiting for start mode from remote.\n");
        mode = RNBRunLoopGetStartModeFromRemote(g_remoteSP);
      } else {
        mode = eRNBRunLoopModeExit;
      }
      break;

    case eRNBRunLoopModeInferiorExecuting:
      mode = RNBRunLoopInferiorExecuting(g_remoteSP);
      break;

    default:
      mode = eRNBRunLoopModeExit;
      break;

    case eRNBRunLoopModeExit:
      break;
    }
  }

  g_remoteSP->StopReadRemoteDataThread();
  g_remoteSP->Context().SetProcessID(INVALID_NUB_PROCESS);

  return 0;
}
