// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <cctype>
#include <cstdlib>
#include <sstream>

#include "src/v8.h"

#include "src/assembler.h"
#include "src/base/functional.h"
#include "src/base/platform/platform.h"
#include "src/ostreams.h"

namespace v8 {
namespace internal {

// Define all of our flags.
#define FLAG_MODE_DEFINE
#include "src/flag-definitions.h"  // NOLINT

// Define all of our flags default values.
#define FLAG_MODE_DEFINE_DEFAULTS
#include "src/flag-definitions.h"  // NOLINT

namespace {

// This structure represents a single entry in the flag system, with a pointer
// to the actual flag, default value, comment, etc.  This is designed to be POD
// initialized as to avoid requiring static constructors.
struct Flag {
  enum FlagType { TYPE_BOOL, TYPE_MAYBE_BOOL, TYPE_INT, TYPE_FLOAT,
                  TYPE_STRING, TYPE_ARGS };

  FlagType type_;           // What type of flag, bool, int, or string.
  const char* name_;        // Name of the flag, ex "my_flag".
  void* valptr_;            // Pointer to the global flag variable.
  const void* defptr_;      // Pointer to the default value.
  const char* cmt_;         // A comment about the flags purpose.
  bool owns_ptr_;           // Does the flag own its string value?

  FlagType type() const { return type_; }

  const char* name() const { return name_; }

  const char* comment() const { return cmt_; }

  bool* bool_variable() const {
    DCHECK(type_ == TYPE_BOOL);
    return reinterpret_cast<bool*>(valptr_);
  }

  MaybeBoolFlag* maybe_bool_variable() const {
    DCHECK(type_ == TYPE_MAYBE_BOOL);
    return reinterpret_cast<MaybeBoolFlag*>(valptr_);
  }

  int* int_variable() const {
    DCHECK(type_ == TYPE_INT);
    return reinterpret_cast<int*>(valptr_);
  }

  double* float_variable() const {
    DCHECK(type_ == TYPE_FLOAT);
    return reinterpret_cast<double*>(valptr_);
  }

  const char* string_value() const {
    DCHECK(type_ == TYPE_STRING);
    return *reinterpret_cast<const char**>(valptr_);
  }

  void set_string_value(const char* value, bool owns_ptr) {
    DCHECK(type_ == TYPE_STRING);
    const char** ptr = reinterpret_cast<const char**>(valptr_);
    if (owns_ptr_ && *ptr != NULL) DeleteArray(*ptr);
    *ptr = value;
    owns_ptr_ = owns_ptr;
  }

  JSArguments* args_variable() const {
    DCHECK(type_ == TYPE_ARGS);
    return reinterpret_cast<JSArguments*>(valptr_);
  }

  bool bool_default() const {
    DCHECK(type_ == TYPE_BOOL);
    return *reinterpret_cast<const bool*>(defptr_);
  }

  int int_default() const {
    DCHECK(type_ == TYPE_INT);
    return *reinterpret_cast<const int*>(defptr_);
  }

  double float_default() const {
    DCHECK(type_ == TYPE_FLOAT);
    return *reinterpret_cast<const double*>(defptr_);
  }

  const char* string_default() const {
    DCHECK(type_ == TYPE_STRING);
    return *reinterpret_cast<const char* const *>(defptr_);
  }

  JSArguments args_default() const {
    DCHECK(type_ == TYPE_ARGS);
    return *reinterpret_cast<const JSArguments*>(defptr_);
  }

  // Compare this flag's current value against the default.
  bool IsDefault() const {
    switch (type_) {
      case TYPE_BOOL:
        return *bool_variable() == bool_default();
      case TYPE_MAYBE_BOOL:
        return maybe_bool_variable()->has_value == false;
      case TYPE_INT:
        return *int_variable() == int_default();
      case TYPE_FLOAT:
        return *float_variable() == float_default();
      case TYPE_STRING: {
        const char* str1 = string_value();
        const char* str2 = string_default();
        if (str2 == NULL) return str1 == NULL;
        if (str1 == NULL) return str2 == NULL;
        return strcmp(str1, str2) == 0;
      }
      case TYPE_ARGS:
        return args_variable()->argc == 0;
    }
    UNREACHABLE();
    return true;
  }

  // Set a flag back to it's default value.
  void Reset() {
    switch (type_) {
      case TYPE_BOOL:
        *bool_variable() = bool_default();
        break;
      case TYPE_MAYBE_BOOL:
        *maybe_bool_variable() = MaybeBoolFlag::Create(false, false);
        break;
      case TYPE_INT:
        *int_variable() = int_default();
        break;
      case TYPE_FLOAT:
        *float_variable() = float_default();
        break;
      case TYPE_STRING:
        set_string_value(string_default(), false);
        break;
      case TYPE_ARGS:
        *args_variable() = args_default();
        break;
    }
  }
};

Flag flags[] = {
#define FLAG_MODE_META
#include "src/flag-definitions.h"
};

const size_t num_flags = sizeof(flags) / sizeof(*flags);

}  // namespace


static const char* Type2String(Flag::FlagType type) {
  switch (type) {
    case Flag::TYPE_BOOL: return "bool";
    case Flag::TYPE_MAYBE_BOOL: return "maybe_bool";
    case Flag::TYPE_INT: return "int";
    case Flag::TYPE_FLOAT: return "float";
    case Flag::TYPE_STRING: return "string";
    case Flag::TYPE_ARGS: return "arguments";
  }
  UNREACHABLE();
  return NULL;
}


std::ostream& operator<<(std::ostream& os, const Flag& flag) {  // NOLINT
  switch (flag.type()) {
    case Flag::TYPE_BOOL:
      os << (*flag.bool_variable() ? "true" : "false");
      break;
    case Flag::TYPE_MAYBE_BOOL:
      os << (flag.maybe_bool_variable()->has_value
                 ? (flag.maybe_bool_variable()->value ? "true" : "false")
                 : "unset");
      break;
    case Flag::TYPE_INT:
      os << *flag.int_variable();
      break;
    case Flag::TYPE_FLOAT:
      os << *flag.float_variable();
      break;
    case Flag::TYPE_STRING: {
      const char* str = flag.string_value();
      os << (str ? str : "NULL");
      break;
    }
    case Flag::TYPE_ARGS: {
      JSArguments args = *flag.args_variable();
      if (args.argc > 0) {
        os << args[0];
        for (int i = 1; i < args.argc; i++) {
          os << args[i];
        }
      }
      break;
    }
  }
  return os;
}


// static
List<const char*>* FlagList::argv() {
  List<const char*>* args = new List<const char*>(8);
  Flag* args_flag = NULL;
  for (size_t i = 0; i < num_flags; ++i) {
    Flag* f = &flags[i];
    if (!f->IsDefault()) {
      if (f->type() == Flag::TYPE_ARGS) {
        DCHECK(args_flag == NULL);
        args_flag = f;  // Must be last in arguments.
        continue;
      }
      {
        bool disabled = f->type() == Flag::TYPE_BOOL && !*f->bool_variable();
        std::ostringstream os;
        os << (disabled ? "--no" : "--") << f->name();
        args->Add(StrDup(os.str().c_str()));
      }
      if (f->type() != Flag::TYPE_BOOL) {
        std::ostringstream os;
        os << *f;
        args->Add(StrDup(os.str().c_str()));
      }
    }
  }
  if (args_flag != NULL) {
    std::ostringstream os;
    os << "--" << args_flag->name();
    args->Add(StrDup(os.str().c_str()));
    JSArguments jsargs = *args_flag->args_variable();
    for (int j = 0; j < jsargs.argc; j++) {
      args->Add(StrDup(jsargs[j]));
    }
  }
  return args;
}


inline char NormalizeChar(char ch) {
  return ch == '_' ? '-' : ch;
}


// Helper function to parse flags: Takes an argument arg and splits it into
// a flag name and flag value (or NULL if they are missing). is_bool is set
// if the arg started with "-no" or "--no". The buffer may be used to NUL-
// terminate the name, it must be large enough to hold any possible name.
static void SplitArgument(const char* arg,
                          char* buffer,
                          int buffer_size,
                          const char** name,
                          const char** value,
                          bool* is_bool) {
  *name = NULL;
  *value = NULL;
  *is_bool = false;

  if (arg != NULL && *arg == '-') {
    // find the begin of the flag name
    arg++;  // remove 1st '-'
    if (*arg == '-') {
      arg++;  // remove 2nd '-'
      if (arg[0] == '\0') {
        const char* kJSArgumentsFlagName = "js_arguments";
        *name = kJSArgumentsFlagName;
        return;
      }
    }
    if (arg[0] == 'n' && arg[1] == 'o') {
      arg += 2;  // remove "no"
      if (NormalizeChar(arg[0]) == '-') arg++;  // remove dash after "no".
      *is_bool = true;
    }
    *name = arg;

    // find the end of the flag name
    while (*arg != '\0' && *arg != '=')
      arg++;

    // get the value if any
    if (*arg == '=') {
      // make a copy so we can NUL-terminate flag name
      size_t n = arg - *name;
      CHECK(n < static_cast<size_t>(buffer_size));  // buffer is too small
      MemCopy(buffer, *name, n);
      buffer[n] = '\0';
      *name = buffer;
      // get the value
      *value = arg + 1;
    }
  }
}


static bool EqualNames(const char* a, const char* b) {
  for (int i = 0; NormalizeChar(a[i]) == NormalizeChar(b[i]); i++) {
    if (a[i] == '\0') {
      return true;
    }
  }
  return false;
}


static Flag* FindFlag(const char* name) {
  for (size_t i = 0; i < num_flags; ++i) {
    if (EqualNames(name, flags[i].name()))
      return &flags[i];
  }
  return NULL;
}


// static
int FlagList::SetFlagsFromCommandLine(int* argc,
                                      char** argv,
                                      bool remove_flags) {
  int return_code = 0;
  // parse arguments
  for (int i = 1; i < *argc;) {
    int j = i;  // j > 0
    const char* arg = argv[i++];

    // split arg into flag components
    char buffer[1*KB];
    const char* name;
    const char* value;
    bool is_bool;
    SplitArgument(arg, buffer, sizeof buffer, &name, &value, &is_bool);

    if (name != NULL) {
      // lookup the flag
      Flag* flag = FindFlag(name);
      if (flag == NULL) {
        if (remove_flags) {
          // We don't recognize this flag but since we're removing
          // the flags we recognize we assume that the remaining flags
          // will be processed somewhere else so this flag might make
          // sense there.
          continue;
        } else {
          PrintF(stderr, "Error: unrecognized flag %s\n"
                 "Try --help for options\n", arg);
          return_code = j;
          break;
        }
      }

      // if we still need a flag value, use the next argument if available
      if (flag->type() != Flag::TYPE_BOOL &&
          flag->type() != Flag::TYPE_MAYBE_BOOL &&
          flag->type() != Flag::TYPE_ARGS &&
          value == NULL) {
        if (i < *argc) {
          value = argv[i++];
        }
        if (!value) {
          PrintF(stderr, "Error: missing value for flag %s of type %s\n"
                 "Try --help for options\n",
                 arg, Type2String(flag->type()));
          return_code = j;
          break;
        }
      }

      // set the flag
      char* endp = const_cast<char*>("");  // *endp is only read
      switch (flag->type()) {
        case Flag::TYPE_BOOL:
          *flag->bool_variable() = !is_bool;
          break;
        case Flag::TYPE_MAYBE_BOOL:
          *flag->maybe_bool_variable() = MaybeBoolFlag::Create(true, !is_bool);
          break;
        case Flag::TYPE_INT:
          *flag->int_variable() = strtol(value, &endp, 10);  // NOLINT
          break;
        case Flag::TYPE_FLOAT:
          *flag->float_variable() = strtod(value, &endp);
          break;
        case Flag::TYPE_STRING:
          flag->set_string_value(value ? StrDup(value) : NULL, true);
          break;
        case Flag::TYPE_ARGS: {
          int start_pos = (value == NULL) ? i : i - 1;
          int js_argc = *argc - start_pos;
          const char** js_argv = NewArray<const char*>(js_argc);
          if (value != NULL) {
            js_argv[0] = StrDup(value);
          }
          for (int k = i; k < *argc; k++) {
            js_argv[k - start_pos] = StrDup(argv[k]);
          }
          *flag->args_variable() = JSArguments::Create(js_argc, js_argv);
          i = *argc;  // Consume all arguments
          break;
        }
      }

      // handle errors
      bool is_bool_type = flag->type() == Flag::TYPE_BOOL ||
          flag->type() == Flag::TYPE_MAYBE_BOOL;
      if ((is_bool_type && value != NULL) || (!is_bool_type && is_bool) ||
          *endp != '\0') {
        PrintF(stderr, "Error: illegal value for flag %s of type %s\n"
               "Try --help for options\n",
               arg, Type2String(flag->type()));
        return_code = j;
        break;
      }

      // remove the flag & value from the command
      if (remove_flags) {
        while (j < i) {
          argv[j++] = NULL;
        }
      }
    }
  }

  // shrink the argument list
  if (remove_flags) {
    int j = 1;
    for (int i = 1; i < *argc; i++) {
      if (argv[i] != NULL)
        argv[j++] = argv[i];
    }
    *argc = j;
  }

  if (FLAG_help) {
    PrintHelp();
    exit(0);
  }
  // parsed all flags successfully
  return return_code;
}


static char* SkipWhiteSpace(char* p) {
  while (*p != '\0' && isspace(*p) != 0) p++;
  return p;
}


static char* SkipBlackSpace(char* p) {
  while (*p != '\0' && isspace(*p) == 0) p++;
  return p;
}


// static
int FlagList::SetFlagsFromString(const char* str, int len) {
  // make a 0-terminated copy of str
  ScopedVector<char> copy0(len + 1);
  MemCopy(copy0.start(), str, len);
  copy0[len] = '\0';

  // strip leading white space
  char* copy = SkipWhiteSpace(copy0.start());

  // count the number of 'arguments'
  int argc = 1;  // be compatible with SetFlagsFromCommandLine()
  for (char* p = copy; *p != '\0'; argc++) {
    p = SkipBlackSpace(p);
    p = SkipWhiteSpace(p);
  }

  // allocate argument array
  ScopedVector<char*> argv(argc);

  // split the flags string into arguments
  argc = 1;  // be compatible with SetFlagsFromCommandLine()
  for (char* p = copy; *p != '\0'; argc++) {
    argv[argc] = p;
    p = SkipBlackSpace(p);
    if (*p != '\0') *p++ = '\0';  // 0-terminate argument
    p = SkipWhiteSpace(p);
  }

  // set the flags
  int result = SetFlagsFromCommandLine(&argc, argv.start(), false);

  return result;
}


// static
void FlagList::ResetAllFlags() {
  for (size_t i = 0; i < num_flags; ++i) {
    flags[i].Reset();
  }
}


// static
void FlagList::PrintHelp() {
  CpuFeatures::Probe(false);
  CpuFeatures::PrintTarget();
  CpuFeatures::PrintFeatures();

  OFStream os(stdout);
  os << "Usage:\n"
     << "  shell [options] -e string\n"
     << "    execute string in V8\n"
     << "  shell [options] file1 file2 ... filek\n"
     << "    run JavaScript scripts in file1, file2, ..., filek\n"
     << "  shell [options]\n"
     << "  shell [options] --shell [file1 file2 ... filek]\n"
     << "    run an interactive JavaScript shell\n"
     << "  d8 [options] file1 file2 ... filek\n"
     << "  d8 [options]\n"
     << "  d8 [options] --shell [file1 file2 ... filek]\n"
     << "    run the new debugging shell\n\n"
     << "Options:\n";
  for (size_t i = 0; i < num_flags; ++i) {
    Flag* f = &flags[i];
    os << "  --" << f->name() << " (" << f->comment() << ")\n"
       << "        type: " << Type2String(f->type()) << "  default: " << *f
       << "\n";
  }
}


// static
void FlagList::EnforceFlagImplications() {
#define FLAG_MODE_DEFINE_IMPLICATIONS
#include "src/flag-definitions.h"
#undef FLAG_MODE_DEFINE_IMPLICATIONS
}


uint32_t FlagList::Hash() {
  std::ostringstream modified_args_as_string;
  for (size_t i = 0; i < num_flags; ++i) {
    Flag* current = &flags[i];
    if (!current->IsDefault()) {
      modified_args_as_string << i;
      modified_args_as_string << *current;
    }
  }
  std::string args(modified_args_as_string.str());
  return static_cast<uint32_t>(
      base::hash_range(args.c_str(), args.c_str() + args.length()));
}
} }  // namespace v8::internal
