#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>

#if USE_SYSLOG
#include <pwd.h>
#include <sys/types.h>
#include <syslog.h>
#endif

#include <sysutils/SocketClient.h>
#include <bootloader.h>

#include "command_listener.h"
#include "sync_fts_prop.h"
#include "watchdog_service.h"

// Reboot command format
//      "reboot now"
//      "reboot set FDR"
//      "reboot set OTA"
//      "reboot clear OTA"
//
// Reboot response format
//      success:    "000 Success"
//      failure:    "xxx Failure yyyy"
//                      xxx is 3-digit error code (255 = -1)
//                      yyyy is error string generated by strerror().

namespace {
class RebootServiceCommand : public FrameworkCommand {
public:
    explicit RebootServiceCommand(const char *cmd);
    virtual ~RebootServiceCommand() {}
    virtual int runCommand(SocketClient *c, int argc, char ** argv);

private:
    int sendResponse(SocketClient *cli, int ret) const;
#if USE_SYSLOG
    void printCommand(SocketClient *cli, int argc, char *argv[]) const;
#endif
    int rebootNow(SocketClient *cli);
    int doRecovery(const char *cmd1, const char *cmd2);
    int writeRecoveryParameter() const;

    bool rebooting_;
    bool set_fdr_for_next_reboot_;
    bool set_ota_for_next_reboot_;
};

// command format and command file for /cache/recovery
const char OTA_PARAMETER[] = "--update_package=/cache/ota.zip";
const char FDR_PARAMETER[] = "--wipe_data";
const char OTA_FDR_PARAMETER[] = "--update_package=/cache/ota.zip\n--wipe_data";


}
// stub function to suppress compilation error. It should never be called.
// librecovery calls set_bootloader_message_default(), which is defined in
// bootable/recovery/bootlaoder.c. It's a fallback implementation when fts
// is not available.
extern "C" int set_bootloader_message_default(
        const struct bootloader_message* /* in */) {
#if USE_SYSLOG
    syslog(LOG_ERR, "should use fts and never come here");
#endif
    // Some system doens't support fts, but that is OK.
    return 0;
}

// commandlistener to socket /dev/socket/watchdog
CommandListener::CommandListener() :
                 FrameworkListener("watchdog") {
    registerCmd(new RebootServiceCommand("reboot"));
}

RebootServiceCommand::RebootServiceCommand(const char *cmd)
    : FrameworkCommand(cmd),
      rebooting_(false),
      set_fdr_for_next_reboot_(false),
      set_ota_for_next_reboot_(false) {
}

int RebootServiceCommand::runCommand(SocketClient *cli,
                   int argc, char **argv) {
    int ret;

#if USE_SYSLOG
    printCommand(cli, argc, argv);
#endif

    if (argc < 2 || argc > 3) {
        sendResponse(cli, -EINVAL);
        return 0;
    }

    if (rebooting_) {
        syslog(LOG_INFO, "already rebooting");
        sendResponse(cli, 0);
        return 0;
    }

    if (argc == 2) {
        // "reboot now"
        if (!strcmp("now", argv[1])) {
            return rebootNow(cli);
        } else {
            return sendResponse(cli, -EINVAL);
        }
    } else if (argc == 3) {
        // "reboot set FDR"
        // "reboot set OTA"
        // "reboot clear OTA"
        if ((!strcmp("set", argv[1]) &&
            (!strcmp("FDR", argv[2]) || !strcmp("OTA", argv[2]))) ||
            (!strcmp("clear", argv[1]) && !strcmp("OTA", argv[2]))) {
            ret = doRecovery(argv[1], argv[2]);
            return sendResponse(cli, ret);
        } else {
            return sendResponse(cli, -EINVAL);
        }
    } else {
        return sendResponse(cli, -EINVAL);
    }
}

int RebootServiceCommand::sendResponse(SocketClient *cli, int ret) const {
    if (ret) {
        if (cli->sendMsg(ret, "Failure", true)) {
            return -1;
        }
    } else {
        if (cli->sendMsg(ret, "Success", false)) {
            return -1;
        }
    }
    return 0;
}

#if USE_SYSLOG
void RebootServiceCommand::printCommand(SocketClient *cli, int argc,
                                        char *argv[]) const {
    int i;
    pid_t pid = cli->getPid();
    uid_t uid = cli->getUid();
    struct passwd *pwd = getpwuid(uid);

    syslog(LOG_INFO, "received command from process %d, uid %d %s.",
           pid, uid, pwd ? pwd->pw_name : "unknown");
    for (i = 0; i < argc; ++i) {
        syslog(LOG_INFO, "       %s", argv[i]);
    }
}
#endif

int RebootServiceCommand::rebootNow(SocketClient *cli) {
    // reboot is guaranteed to succeed.
    // send response first.
    int ret = sendResponse(cli, 0);
    ret =  reboot_service_request();
    rebooting_ = true;
    return ret;
}

// handler for "reboot set FDR" and "reboot set OTA" command.
// both boots in to recovery mode next time.
int RebootServiceCommand::doRecovery(const char *cmd1, const char *cmd2) {
    if (!cmd2 || !cmd1) {
#if USE_SYSLOG
        syslog(LOG_ERR, "doRecovery cmd is NULL");
#endif
        return -1;
    }

#if USE_SYSLOG
    syslog(LOG_INFO, "reboot service: recovery cmd is %s %s", cmd1, cmd2);
#endif

    if (!strcmp("set", cmd1)) {
      if (!strcmp("FDR", cmd2)) {
          set_fdr_for_next_reboot_ = true;
          increment_fdr_count();
      } else if (!strcmp("OTA", cmd2)) {
          set_ota_for_next_reboot_ = true;
      } else {
          return -1;
      }
    } else if (!strcmp("clear", cmd1) && !strcmp("OTA", cmd2)) {
      set_ota_for_next_reboot_ = false;
    }

    if (writeRecoveryParameter()) {
        return -1;
    }
    return 0;
}

// write boot reocvery parameters to bootloader
int RebootServiceCommand::writeRecoveryParameter() const {
    struct bootloader_message boot;
    memset(&boot, 0, sizeof(boot));

    const char* param;
#ifdef AB_OTA_UPDATER
    if (set_fdr_for_next_reboot_) {
      param = FDR_PARAMETER;
    } else if (set_ota_for_next_reboot_) {
      // We dont need to set anything for AB based products
      return 0;
    } else {
      return -1;
    }
#else
    if (set_fdr_for_next_reboot_ && set_ota_for_next_reboot_) {
      param = OTA_FDR_PARAMETER;
    } else if (set_fdr_for_next_reboot_ && !set_ota_for_next_reboot_) {
      param = FDR_PARAMETER;
    } else if (set_ota_for_next_reboot_ && !set_fdr_for_next_reboot_) {
      param = OTA_PARAMETER;
    } else {
      param = "";
    }
#endif

    if (strcmp(param, "")) {
      strncpy(boot.command, "boot-recovery", sizeof(boot.command) - 1);
      snprintf(boot.recovery, sizeof(boot.recovery) - 1, "recovery\n%s\n", param);
    }
    return set_bootloader_message(&boot);
}
