/*
 * Copyright (C) 2019 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.
 */

#include <ctype.h>
#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>

#include <string>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <modprobe/modprobe.h>

#include <sys/utsname.h>

namespace {

enum modprobe_mode {
    AddModulesMode,
    RemoveModulesMode,
    ListModulesMode,
    ShowDependenciesMode,
};

void print_usage(void) {
    LOG(INFO) << "Usage:";
    LOG(INFO);
    LOG(INFO) << "  modprobe [options] [-d DIR] [--all=FILE|MODULE]...";
    LOG(INFO) << "  modprobe [options] [-d DIR] MODULE [symbol=value]...";
    LOG(INFO);
    LOG(INFO) << "Options:";
    LOG(INFO) << "  --all=FILE: FILE to acquire module names from";
    LOG(INFO) << "  -b, --use-blocklist: Apply blocklist to module names too";
    LOG(INFO) << "  -d, --dirname=DIR: Load modules from DIR, option may be used multiple times";
    LOG(INFO) << "  -D, --show-depends: Print dependencies for modules only, do not load";
    LOG(INFO) << "  -h, --help: Print this help";
    LOG(INFO) << "  -l, --list: List modules matching pattern";
    LOG(INFO) << "  -r, --remove: Remove MODULE (multiple modules may be specified)";
    LOG(INFO) << "  -s, --syslog: print to syslog also";
    LOG(INFO) << "  -q, --quiet: disable messages";
    LOG(INFO) << "  -v, --verbose: enable more messages, even more with a second -v";
    LOG(INFO);
}

#define check_mode()                                   \
    if (mode != AddModulesMode) {                      \
        LOG(ERROR) << "multiple mode flags specified"; \
        print_usage();                                 \
        return EXIT_FAILURE;                           \
    }

std::string stripComments(const std::string& str) {
    for (std::string rv = str;;) {
        auto comment = rv.find('#');
        if (comment == std::string::npos) return rv;
        auto end = rv.find('\n', comment);
        if (end != std::string::npos) end = end - comment;
        rv.erase(comment, end);
    }
    /* NOTREACHED */
}

auto syslog = false;

void MyLogger(android::base::LogId id, android::base::LogSeverity severity, const char* tag,
              const char* file, unsigned int line, const char* message) {
    android::base::StdioLogger(id, severity, tag, file, line, message);
    if (syslog && message[0]) {
        android::base::KernelLogger(id, severity, tag, file, line, message);
    }
}

static bool ModDirMatchesKernelPageSize(const char* mod_dir) {
    static const unsigned int kernel_pgsize_kb = getpagesize() / 1024;
    const char* mod_sfx = strrchr(mod_dir, '_');
    unsigned int mod_pgsize_kb;
    int mod_sfx_len;

    if (mod_sfx == NULL || sscanf(mod_sfx, "_%uk%n", &mod_pgsize_kb, &mod_sfx_len) != 1 ||
        strlen(mod_sfx) != mod_sfx_len) {
        mod_pgsize_kb = 4;
    }

    return kernel_pgsize_kb == mod_pgsize_kb;
}

// Find directories in format of "/lib/modules/x.y.z-*".
static int KernelVersionNameFilter(const dirent* de) {
    unsigned int major, minor;
    static std::string kernel_version;
    utsname uts;

    if (kernel_version.empty()) {
        if ((uname(&uts) != 0) || (sscanf(uts.release, "%u.%u", &major, &minor) != 2)) {
            LOG(ERROR) << "Could not parse the kernel version from uname";
            return 0;
        }
        kernel_version = android::base::StringPrintf("%u.%u", major, minor);
    }

    if (android::base::StartsWith(de->d_name, kernel_version)) {
        return ModDirMatchesKernelPageSize(de->d_name);
    }
    return 0;
}

}  // anonymous namespace

extern "C" int modprobe_main(int argc, char** argv) {
    android::base::InitLogging(argv, MyLogger);
    android::base::SetMinimumLogSeverity(android::base::INFO);

    std::vector<std::string> modules;
    std::string modules_load_file;
    std::string module_parameters;
    std::string mods;
    std::vector<std::string> mod_dirs;
    modprobe_mode mode = AddModulesMode;
    bool blocklist = false;
    int rv = EXIT_SUCCESS;

    int opt, fd;
    int option_index = 0;
    // NB: We have non-standard short options -l and -D to make it easier for
    // OEMs to transition from toybox.
    // clang-format off
    static struct option long_options[] = {
        { "all",                 optional_argument, 0, 'a' },
        { "use-blocklist",       no_argument,       0, 'b' },
        { "dirname",             required_argument, 0, 'd' },
        { "show-depends",        no_argument,       0, 'D' },
        { "help",                no_argument,       0, 'h' },
        { "list",                no_argument,       0, 'l' },
        { "quiet",               no_argument,       0, 'q' },
        { "remove",              no_argument,       0, 'r' },
        { "syslog",              no_argument,       0, 's' },
        { "verbose",             no_argument,       0, 'v' },
    };
    // clang-format on
    while ((opt = getopt_long(argc, argv, "a::bd:Dhlqrsv", long_options, &option_index)) != -1) {
        switch (opt) {
            case 'a':
                // toybox modprobe supported -a to load multiple modules, this
                // is supported here by default, ignore flag if no argument.
                check_mode();
                if (optarg == NULL) break;

                // Since libmodprobe doesn't fail when the modules load file
                // doesn't exist, let's check that here so that we don't
                // silently fail.
                fd = open(optarg, O_RDONLY | O_CLOEXEC | O_BINARY);
                if (fd == -1) {
                    PLOG(ERROR) << "Failed to open " << optarg;
                    return EXIT_FAILURE;
                }
                close(fd);

                mod_dirs.emplace_back(android::base::Dirname(optarg));
                modules_load_file = android::base::Basename(optarg);
                break;
            case 'b':
                blocklist = true;
                break;
            case 'd':
                mod_dirs.emplace_back(optarg);
                break;
            case 'D':
                check_mode();
                mode = ShowDependenciesMode;
                break;
            case 'h':
                android::base::SetMinimumLogSeverity(android::base::INFO);
                print_usage();
                return rv;
            case 'l':
                check_mode();
                mode = ListModulesMode;
                break;
            case 'q':
                android::base::SetMinimumLogSeverity(android::base::WARNING);
                break;
            case 'r':
                check_mode();
                mode = RemoveModulesMode;
                break;
            case 's':
                syslog = true;
                break;
            case 'v':
                if (android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
                    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
                } else {
                    android::base::SetMinimumLogSeverity(android::base::DEBUG);
                }
                break;
            default:
                LOG(ERROR) << "Unrecognized option: " << opt;
                print_usage();
                return EXIT_FAILURE;
        }
    }

    int parameter_count = 0;
    for (opt = optind; opt < argc; opt++) {
        if (!strchr(argv[opt], '=')) {
            modules.emplace_back(argv[opt]);
        } else {
            parameter_count++;
            if (module_parameters.empty()) {
                module_parameters = argv[opt];
            } else {
                module_parameters = module_parameters + " " + argv[opt];
            }
        }
    }

    if (mod_dirs.empty()) {
        static constexpr auto LIB_MODULES_PREFIX = "/lib/modules/";
        dirent** kernel_dirs = NULL;

        int n = scandir(LIB_MODULES_PREFIX, &kernel_dirs, KernelVersionNameFilter, NULL);
        if (n == -1) {
            PLOG(ERROR) << "Failed to scan dir " << LIB_MODULES_PREFIX;
            return EXIT_FAILURE;
        } else if (n > 0) {
            while (n--) {
                mod_dirs.emplace_back(LIB_MODULES_PREFIX + std::string(kernel_dirs[n]->d_name));
            }
        }
        free(kernel_dirs);

        if (mod_dirs.empty() || getpagesize() == 4096) {
            // Allow modules to be directly inside /lib/modules
            mod_dirs.emplace_back(LIB_MODULES_PREFIX);
        }
    }

    LOG(DEBUG) << "mode is " << mode;
    LOG(DEBUG) << "mod_dirs is: " << android::base::Join(mod_dirs, " ");
    LOG(DEBUG) << "modules is: " << android::base::Join(modules, " ");
    LOG(DEBUG) << "modules load file is: " << modules_load_file;
    LOG(DEBUG) << "module parameters is: " << android::base::Join(module_parameters, " ");

    if (modules.empty()) {
        if (mode == ListModulesMode) {
            // emulate toybox modprobe list with no pattern (list all)
            modules.emplace_back("*");
        } else if (modules_load_file.empty()) {
            LOG(ERROR) << "No modules given.";
            print_usage();
            return EXIT_FAILURE;
        }
    }
    if (parameter_count && (modules.size() > 1 || !modules_load_file.empty())) {
        LOG(ERROR) << "Only one module may be loaded when specifying module parameters.";
        print_usage();
        return EXIT_FAILURE;
    }

    Modprobe m(mod_dirs, modules_load_file.empty() ? "modules.load" : modules_load_file, blocklist);
    if (mode == AddModulesMode && !modules_load_file.empty()) {
        if (!m.LoadListedModules(false)) {
            PLOG(ERROR) << "Failed to load all the modules from " << modules_load_file;
            return EXIT_FAILURE;
        }
        /* Fall-through to load modules provided on the command line (if any)*/
    }

    for (const auto& module : modules) {
        switch (mode) {
            case AddModulesMode:
                if (!m.LoadWithAliases(module, true, module_parameters)) {
                    if (m.IsBlocklisted(module)) continue;
                    PLOG(ERROR) << "Failed to load module " << module;
                    rv = EXIT_FAILURE;
                }
                break;
            case RemoveModulesMode:
                if (!m.Remove(module)) {
                    PLOG(ERROR) << "Failed to remove module " << module;
                    rv = EXIT_FAILURE;
                }
                break;
            case ListModulesMode: {
                std::vector<std::string> list = m.ListModules(module);
                LOG(INFO) << android::base::Join(list, "\n");
                break;
            }
            case ShowDependenciesMode: {
                std::vector<std::string> pre_deps;
                std::vector<std::string> deps;
                std::vector<std::string> post_deps;
                if (!m.GetAllDependencies(module, &pre_deps, &deps, &post_deps)) {
                    rv = EXIT_FAILURE;
                    break;
                }
                LOG(INFO) << "Dependencies for " << module << ":";
                LOG(INFO) << "Soft pre-dependencies:";
                LOG(INFO) << android::base::Join(pre_deps, "\n");
                LOG(INFO) << "Hard dependencies:";
                LOG(INFO) << android::base::Join(deps, "\n");
                LOG(INFO) << "Soft post-dependencies:";
                LOG(INFO) << android::base::Join(post_deps, "\n");
                break;
            }
            default:
                LOG(ERROR) << "Bad mode";
                rv = EXIT_FAILURE;
        }
    }

    return rv;
}
