/*
 * 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 <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);
    }
}

// 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 1;
    }
    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 module_parameters;
    std::string mods;
    std::vector<std::string> mod_dirs;
    modprobe_mode mode = AddModulesMode;
    bool blocklist = false;
    int rv = EXIT_SUCCESS;

    int opt;
    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;
                if (!android::base::ReadFileToString(optarg, &mods)) {
                    PLOG(ERROR) << "Failed to open " << optarg;
                    rv = EXIT_FAILURE;
                }
                for (auto mod : android::base::Split(stripComments(mods), "\n")) {
                    mod = android::base::Trim(mod);
                    if (mod == "") continue;
                    if (std::find(modules.begin(), modules.end(), mod) != modules.end()) continue;
                    modules.emplace_back(mod);
                }
                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);

        // 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) << "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 {
            LOG(ERROR) << "No modules given.";
            print_usage();
            return EXIT_FAILURE;
        }
    }
    if (parameter_count && modules.size() > 1) {
        LOG(ERROR) << "Only one module may be loaded when specifying module parameters.";
        print_usage();
        return EXIT_FAILURE;
    }

    Modprobe m(mod_dirs, "modules.load", blocklist);

    for (const auto& module : modules) {
        switch (mode) {
            case AddModulesMode:
                if (!m.LoadWithAliases(module, true, module_parameters)) {
                    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;
}
