/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * SPDX-License-Identifier: curl
 *
 ***************************************************************************/
#include "tool_setup.h"
#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "curlx.h"

#include "tool_help.h"
#include "tool_libinfo.h"
#include "tool_util.h"
#include "tool_version.h"
#include "tool_cb_prg.h"
#include "terminal.h"

#include "memdebug.h" /* keep this as LAST include */

#ifdef MSDOS
#  define USE_WATT32
#endif

struct category_descriptors {
  const char *opt;
  const char *desc;
  curlhelp_t category;
};

static const struct category_descriptors categories[] = {
  {"auth", "Different types of authentication methods", CURLHELP_AUTH},
  {"connection", "Low level networking operations",
   CURLHELP_CONNECTION},
  {"curl", "The command line tool itself", CURLHELP_CURL},
  {"dns", "General DNS options", CURLHELP_DNS},
  {"file", "FILE protocol options", CURLHELP_FILE},
  {"ftp", "FTP protocol options", CURLHELP_FTP},
  {"http", "HTTP and HTTPS protocol options", CURLHELP_HTTP},
  {"imap", "IMAP protocol options", CURLHELP_IMAP},
  /* important is left out because it is the default help page */
  {"misc", "Options that don't fit into any other category", CURLHELP_MISC},
  {"output", "Filesystem output", CURLHELP_OUTPUT},
  {"pop3", "POP3 protocol options", CURLHELP_POP3},
  {"post", "HTTP Post specific options", CURLHELP_POST},
  {"proxy", "All options related to proxies", CURLHELP_PROXY},
  {"scp", "SCP protocol options", CURLHELP_SCP},
  {"sftp", "SFTP protocol options", CURLHELP_SFTP},
  {"smtp", "SMTP protocol options", CURLHELP_SMTP},
  {"ssh", "SSH protocol options", CURLHELP_SSH},
  {"telnet", "TELNET protocol options", CURLHELP_TELNET},
  {"tftp", "TFTP protocol options", CURLHELP_TFTP},
  {"tls", "All TLS/SSL related options", CURLHELP_TLS},
  {"ech", "All Encrypted Client Hello (ECH) options", CURLHELP_ECH},
  {"upload", "All options for uploads",
   CURLHELP_UPLOAD},
  {"verbose", "Options related to any kind of command line output of curl",
   CURLHELP_VERBOSE},
  {NULL, NULL, CURLHELP_HIDDEN}
};

static void print_category(curlhelp_t category, unsigned int cols)
{
  unsigned int i;
  size_t longopt = 5;
  size_t longdesc = 5;

  for(i = 0; helptext[i].opt; ++i) {
    size_t len;
    if(!(helptext[i].categories & category))
      continue;
    len = strlen(helptext[i].opt);
    if(len > longopt)
      longopt = len;
    len = strlen(helptext[i].desc);
    if(len > longdesc)
      longdesc = len;
  }
  if(longopt + longdesc > cols)
    longopt = cols - longdesc;

  for(i = 0; helptext[i].opt; ++i)
    if(helptext[i].categories & category) {
      size_t opt = longopt;
      size_t desclen = strlen(helptext[i].desc);
      if(opt + desclen >= (cols - 2)) {
        if(desclen < (cols - 2))
          opt = (cols - 3) - desclen;
        else
          opt = 0;
      }
      printf(" %-*s  %s\n", (int)opt, helptext[i].opt, helptext[i].desc);
    }
}

/* Prints category if found. If not, it returns 1 */
static int get_category_content(const char *category, unsigned int cols)
{
  unsigned int i;
  for(i = 0; categories[i].opt; ++i)
    if(curl_strequal(categories[i].opt, category)) {
      printf("%s: %s\n", categories[i].opt, categories[i].desc);
      print_category(categories[i].category, cols);
      return 0;
    }
  return 1;
}

/* Prints all categories and their description */
static void get_categories(void)
{
  unsigned int i;
  for(i = 0; categories[i].opt; ++i)
    printf(" %-11s %s\n", categories[i].opt, categories[i].desc);
}


void tool_help(char *category)
{
  unsigned int cols = get_terminal_columns();
  puts("Usage: curl [options...] <url>");
  /* If no category was provided */
  if(!category) {
    const char *category_note = "\nThis is not the full help, this "
      "menu is stripped into categories.\nUse \"--help category\" to get "
      "an overview of all categories.\nFor all options use the manual"
      " or \"--help all\".";
    print_category(CURLHELP_IMPORTANT, cols);
    puts(category_note);
  }
  /* Lets print everything if "all" was provided */
  else if(curl_strequal(category, "all"))
    /* Print everything except hidden */
    print_category(~(CURLHELP_HIDDEN), cols);
  /* Lets handle the string "category" differently to not print an errormsg */
  else if(curl_strequal(category, "category"))
    get_categories();
  /* Otherwise print category and handle the case if the cat was not found */
  else if(get_category_content(category, cols)) {
    puts("Invalid category provided, here is a list of all categories:\n");
    get_categories();
  }
  free(category);
}

static bool is_debug(void)
{
  const char *const *builtin;
  for(builtin = feature_names; *builtin; ++builtin)
    if(curl_strequal("debug", *builtin))
      return TRUE;
  return FALSE;
}

void tool_version_info(void)
{
  const char *const *builtin;
  if(is_debug())
    fprintf(tool_stderr, "WARNING: this libcurl is Debug-enabled, "
            "do not use in production\n\n");

  printf(CURL_ID "%s\n", curl_version());
#ifdef CURL_PATCHSTAMP
  printf("Release-Date: %s, security patched: %s\n",
         LIBCURL_TIMESTAMP, CURL_PATCHSTAMP);
#else
  printf("Release-Date: %s\n", LIBCURL_TIMESTAMP);
#endif
  if(built_in_protos[0]) {
    const char *insert = NULL;
    /* we have ipfs and ipns support if libcurl has http support */
    for(builtin = built_in_protos; *builtin; ++builtin) {
      if(insert) {
        /* update insertion so ipfs will be printed in alphabetical order */
        if(strcmp(*builtin, "ipfs") < 0)
          insert = *builtin;
        else
          break;
      }
      else if(!strcmp(*builtin, "http")) {
        insert = *builtin;
      }
    }
    printf("Protocols:");
    for(builtin = built_in_protos; *builtin; ++builtin) {
      /* Special case: do not list rtmp?* protocols.
         They may only appear together with "rtmp" */
      if(!curl_strnequal(*builtin, "rtmp", 4) || !builtin[0][4])
        printf(" %s", *builtin);
      if(insert && insert == *builtin) {
        printf(" ipfs ipns");
        insert = NULL;
      }
    }
    puts(""); /* newline */
  }
  if(feature_names[0]) {
    printf("Features:");
    for(builtin = feature_names; *builtin; ++builtin)
      printf(" %s", *builtin);
    puts(""); /* newline */
  }
  if(strcmp(CURL_VERSION, curlinfo->version)) {
    printf("WARNING: curl and libcurl versions do not match. "
           "Functionality may be affected.\n");
  }
}

void tool_list_engines(void)
{
  CURL *curl = curl_easy_init();
  struct curl_slist *engines = NULL;

  /* Get the list of engines */
  curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, &engines);

  puts("Build-time engines:");
  if(engines) {
    for(; engines; engines = engines->next)
      printf("  %s\n", engines->data);
  }
  else {
    puts("  <none>");
  }

  /* Cleanup the list of engines */
  curl_slist_free_all(engines);
  curl_easy_cleanup(curl);
}
