/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "dumpstate"

#include "DumpstateUtil.h"

#include <dirent.h>
#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <unistd.h>

#include <vector>

#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/log.h>

#include "DumpstateInternal.h"

namespace android {
namespace os {
namespace dumpstate {

namespace {

static constexpr const char* kSuPath = "/system/xbin/su";

static bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) {
    sigset_t child_mask, old_mask;
    sigemptyset(&child_mask);
    sigaddset(&child_mask, SIGCHLD);

    if (sigprocmask(SIG_BLOCK, &child_mask, &old_mask) == -1) {
        printf("*** sigprocmask failed: %s\n", strerror(errno));
        return false;
    }

    timespec ts;
    ts.tv_sec = timeout_seconds;
    ts.tv_nsec = 0;
    int ret = TEMP_FAILURE_RETRY(sigtimedwait(&child_mask, NULL, &ts));
    int saved_errno = errno;
    // Set the signals back the way they were.
    if (sigprocmask(SIG_SETMASK, &old_mask, NULL) == -1) {
        printf("*** sigprocmask failed: %s\n", strerror(errno));
        if (ret == 0) {
            return false;
        }
    }
    if (ret == -1) {
        errno = saved_errno;
        if (errno == EAGAIN) {
            errno = ETIMEDOUT;
        } else {
            printf("*** sigtimedwait failed: %s\n", strerror(errno));
        }
        return false;
    }

    pid_t child_pid = waitpid(pid, status, WNOHANG);
    if (child_pid != pid) {
        if (child_pid != -1) {
            printf("*** Waiting for pid %d, got pid %d instead\n", pid, child_pid);
        } else {
            printf("*** waitpid failed: %s\n", strerror(errno));
        }
        return false;
    }
    return true;
}
}  // unnamed namespace

CommandOptions CommandOptions::DEFAULT = CommandOptions::WithTimeout(10).Build();
CommandOptions CommandOptions::AS_ROOT = CommandOptions::WithTimeout(10).AsRoot().Build();

CommandOptions::CommandOptionsBuilder::CommandOptionsBuilder(int64_t timeout) : values(timeout) {
}

CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::Always() {
    values.always_ = true;
    return *this;
}

CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::AsRoot() {
    values.account_mode_ = SU_ROOT;
    return *this;
}

CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::AsRootIfAvailable() {
    if (!PropertiesHelper::IsUserBuild())
        values.account_mode_ = SU_ROOT;
    return *this;
}

CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::DropRoot() {
    values.account_mode_ = DROP_ROOT;
    return *this;
}

CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::RedirectStderr() {
    values.output_mode_ = REDIRECT_TO_STDERR;
    return *this;
}

CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::Log(
    const std::string& message) {
    values.logging_message_ = message;
    return *this;
}

CommandOptions CommandOptions::CommandOptionsBuilder::Build() {
    return CommandOptions(values);
}

CommandOptions::CommandOptionsValues::CommandOptionsValues(int64_t timeout)
    : timeout_(timeout),
      always_(false),
      account_mode_(DONT_DROP_ROOT),
      output_mode_(NORMAL_OUTPUT),
      logging_message_("") {
}

CommandOptions::CommandOptions(const CommandOptionsValues& values) : values(values) {
}

int64_t CommandOptions::Timeout() const {
    return values.timeout_;
}

bool CommandOptions::Always() const {
    return values.always_;
}

PrivilegeMode CommandOptions::PrivilegeMode() const {
    return values.account_mode_;
}

OutputMode CommandOptions::OutputMode() const {
    return values.output_mode_;
}

std::string CommandOptions::LoggingMessage() const {
    return values.logging_message_;
}

CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeout(int64_t timeout) {
    return CommandOptions::CommandOptionsBuilder(timeout);
}

std::string PropertiesHelper::build_type_ = "";
int PropertiesHelper::dry_run_ = -1;

bool PropertiesHelper::IsUserBuild() {
    if (build_type_.empty()) {
        build_type_ = android::base::GetProperty("ro.build.type", "user");
    }
    return "user" == build_type_;
}

bool PropertiesHelper::IsDryRun() {
    if (dry_run_ == -1) {
        dry_run_ = android::base::GetBoolProperty("dumpstate.dry_run", false) ? 1 : 0;
    }
    return dry_run_ == 1;
}

int DumpFileToFd(int out_fd, const std::string& title, const std::string& path) {
    int fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC));
    if (fd < 0) {
        int err = errno;
        if (title.empty()) {
            dprintf(out_fd, "*** Error dumping %s: %s\n", path.c_str(), strerror(err));
        } else {
            dprintf(out_fd, "*** Error dumping %s (%s): %s\n", path.c_str(), title.c_str(),
                    strerror(err));
        }
        fsync(out_fd);
        return -1;
    }
    return DumpFileFromFdToFd(title, path, fd, out_fd, PropertiesHelper::IsDryRun());
}

int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
                   const CommandOptions& options) {
    if (full_command.empty()) {
        MYLOGE("No arguments on RunCommandToFd(%s)\n", title.c_str());
        return -1;
    }

    int size = full_command.size() + 1;  // null terminated
    int starting_index = 0;
    if (options.PrivilegeMode() == SU_ROOT) {
        starting_index = 2;  // "su" "root"
        size += starting_index;
    }

    std::vector<const char*> args;
    args.resize(size);

    std::string command_string;
    if (options.PrivilegeMode() == SU_ROOT) {
        args[0] = kSuPath;
        command_string += kSuPath;
        args[1] = "root";
        command_string += " root ";
    }
    for (size_t i = 0; i < full_command.size(); i++) {
        args[i + starting_index] = full_command[i].data();
        command_string += args[i + starting_index];
        if (i != full_command.size() - 1) {
            command_string += " ";
        }
    }
    args[size - 1] = nullptr;

    const char* command = command_string.c_str();

    if (options.PrivilegeMode() == SU_ROOT && PropertiesHelper::IsUserBuild()) {
        dprintf(fd, "Skipping '%s' on user build.\n", command);
        return 0;
    }

    if (!title.empty()) {
        dprintf(fd, "------ %s (%s) ------\n", title.c_str(), command);
        fsync(fd);
    }

    const std::string& logging_message = options.LoggingMessage();
    if (!logging_message.empty()) {
        MYLOGI(logging_message.c_str(), command_string.c_str());
    }

    bool silent = (options.OutputMode() == REDIRECT_TO_STDERR);
    bool redirecting_to_fd = STDOUT_FILENO != fd;

    if (PropertiesHelper::IsDryRun() && !options.Always()) {
        if (!title.empty()) {
            dprintf(fd, "\t(skipped on dry run)\n");
        } else if (redirecting_to_fd) {
            // There is no title, but we should still print a dry-run message
            dprintf(fd, "%s: skipped on dry run\n", command_string.c_str());
        }
        fsync(fd);
        return 0;
    }

    const char* path = args[0];

    uint64_t start = Nanotime();
    pid_t pid = fork();

    /* handle error case */
    if (pid < 0) {
        if (!silent) dprintf(fd, "*** fork: %s\n", strerror(errno));
        MYLOGE("*** fork: %s\n", strerror(errno));
        return pid;
    }

    /* handle child case */
    if (pid == 0) {
        if (options.PrivilegeMode() == DROP_ROOT && !DropRootUser()) {
            if (!silent) {
                dprintf(fd, "*** failed to drop root before running %s: %s\n", command,
                        strerror(errno));
            }
            MYLOGE("*** could not drop root before running %s: %s\n", command, strerror(errno));
            return -1;
        }

        if (silent) {
            // Redirects stdout to stderr
            TEMP_FAILURE_RETRY(dup2(STDERR_FILENO, STDOUT_FILENO));
        } else if (redirecting_to_fd) {
            // Redirect stdout to fd
            TEMP_FAILURE_RETRY(dup2(fd, STDOUT_FILENO));
            close(fd);
        }

        /* make sure the child dies when dumpstate dies */
        prctl(PR_SET_PDEATHSIG, SIGKILL);

        /* just ignore SIGPIPE, will go down with parent's */
        struct sigaction sigact;
        memset(&sigact, 0, sizeof(sigact));
        sigact.sa_handler = SIG_IGN;
        sigaction(SIGPIPE, &sigact, NULL);

        execvp(path, (char**)args.data());
        // execvp's result will be handled after waitpid_with_timeout() below, but
        // if it failed, it's safer to exit dumpstate.
        MYLOGD("execvp on command '%s' failed (error: %s)\n", command, strerror(errno));
        // Must call _exit (instead of exit), otherwise it will corrupt the zip
        // file.
        _exit(EXIT_FAILURE);
    }

    /* handle parent case */
    int status;
    bool ret = waitpid_with_timeout(pid, options.Timeout(), &status);
    fsync(fd);

    uint64_t elapsed = Nanotime() - start;
    if (!ret) {
        if (errno == ETIMEDOUT) {
            if (!silent)
                dprintf(fd, "*** command '%s' timed out after %.3fs (killing pid %d)\n", command,
                        static_cast<float>(elapsed) / NANOS_PER_SEC, pid);
            MYLOGE("*** command '%s' timed out after %.3fs (killing pid %d)\n", command,
                   static_cast<float>(elapsed) / NANOS_PER_SEC, pid);
        } else {
            if (!silent)
                dprintf(fd, "*** command '%s': Error after %.4fs (killing pid %d)\n", command,
                        static_cast<float>(elapsed) / NANOS_PER_SEC, pid);
            MYLOGE("command '%s': Error after %.4fs (killing pid %d)\n", command,
                   static_cast<float>(elapsed) / NANOS_PER_SEC, pid);
        }
        kill(pid, SIGTERM);
        if (!waitpid_with_timeout(pid, 5, nullptr)) {
            kill(pid, SIGKILL);
            if (!waitpid_with_timeout(pid, 5, nullptr)) {
                if (!silent)
                    dprintf(fd, "could not kill command '%s' (pid %d) even with SIGKILL.\n",
                            command, pid);
                MYLOGE("could not kill command '%s' (pid %d) even with SIGKILL.\n", command, pid);
            }
        }
        return -1;
    }

    if (WIFSIGNALED(status)) {
        if (!silent)
            dprintf(fd, "*** command '%s' failed: killed by signal %d\n", command, WTERMSIG(status));
        MYLOGE("*** command '%s' failed: killed by signal %d\n", command, WTERMSIG(status));
    } else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
        status = WEXITSTATUS(status);
        if (!silent) dprintf(fd, "*** command '%s' failed: exit code %d\n", command, status);
        MYLOGE("*** command '%s' failed: exit code %d\n", command, status);
    }

    return status;
}

int GetPidByName(const std::string& ps_name) {
    DIR* proc_dir;
    struct dirent* ps;
    unsigned int pid;
    std::string cmdline;

    if (!(proc_dir = opendir("/proc"))) {
        MYLOGE("Can't open /proc\n");
        return -1;
    }

    while ((ps = readdir(proc_dir))) {
        if (!(pid = atoi(ps->d_name))) {
            continue;
        }
        android::base::ReadFileToString("/proc/" + std::string(ps->d_name) + "/cmdline", &cmdline);
        if (cmdline.find(ps_name) == std::string::npos) {
            continue;
        } else {
            closedir(proc_dir);
            return pid;
        }
    }
    MYLOGE("can't find the pid\n");
    closedir(proc_dir);
    return -1;
}

}  // namespace dumpstate
}  // namespace os
}  // namespace android
