/*
 * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/crypto.h>
#include "apps.h"
#include "progs.h"

typedef enum OPTION_choice {
    OPT_COMMON,
    OPT_CONFIGDIR, OPT_MODULESDIR, OPT_DSOEXT, OPT_DIRNAMESEP,
    OPT_LISTSEP, OPT_SEEDS, OPT_CPUSETTINGS, OPT_WINDOWSCONTEXT
} OPTION_CHOICE;

const OPTIONS info_options[] = {

    OPT_SECTION("General"),
    {"help", OPT_HELP, '-', "Display this summary"},

    OPT_SECTION("Output"),
    {"configdir", OPT_CONFIGDIR, '-', "Default configuration file directory"},
    {"modulesdir", OPT_MODULESDIR, '-',
     "Default module directory (other than engine modules)"},
    {"dsoext", OPT_DSOEXT, '-', "Configured extension for modules"},
    {"dirnamesep", OPT_DIRNAMESEP, '-', "Directory-filename separator"},
    {"listsep", OPT_LISTSEP, '-', "List separator character"},
    {"seeds", OPT_SEEDS, '-', "Seed sources"},
    {"cpusettings", OPT_CPUSETTINGS, '-', "CPU settings info"},
    {"windowscontext", OPT_WINDOWSCONTEXT, '-', "Windows install context"},
    {NULL}
};

int info_main(int argc, char **argv)
{
    int ret = 1, dirty = 0, type = 0;
    char *prog;
    OPTION_CHOICE o;
    const char *typedata;

    prog = opt_init(argc, argv, info_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        default:
opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(info_options);
            ret = 0;
            goto end;
        case OPT_CONFIGDIR:
            type = OPENSSL_INFO_CONFIG_DIR;
            dirty++;
            break;
        case OPT_MODULESDIR:
            type = OPENSSL_INFO_MODULES_DIR;
            dirty++;
            break;
        case OPT_DSOEXT:
            type = OPENSSL_INFO_DSO_EXTENSION;
            dirty++;
            break;
        case OPT_DIRNAMESEP:
            type = OPENSSL_INFO_DIR_FILENAME_SEPARATOR;
            dirty++;
            break;
        case OPT_LISTSEP:
            type = OPENSSL_INFO_LIST_SEPARATOR;
            dirty++;
            break;
        case OPT_SEEDS:
            type = OPENSSL_INFO_SEED_SOURCE;
            dirty++;
            break;
        case OPT_CPUSETTINGS:
            type = OPENSSL_INFO_CPU_SETTINGS;
            dirty++;
            break;
        case OPT_WINDOWSCONTEXT:
            type = OPENSSL_INFO_WINDOWS_CONTEXT;
            dirty++;
            break;
        }
    }
    if (!opt_check_rest_arg(NULL))
        goto opthelp;
    if (dirty > 1) {
        BIO_printf(bio_err, "%s: Only one item allowed\n", prog);
        goto opthelp;
    }
    if (dirty == 0) {
        BIO_printf(bio_err, "%s: No items chosen\n", prog);
        goto opthelp;
    }

    typedata = OPENSSL_info(type);
    BIO_printf(bio_out, "%s\n", typedata == NULL ? "Undefined" : typedata);
    ret = 0;
 end:
    return ret;
}
