/**
* Copyright (C) 2020 Xilinx, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may
* not use this file except in compliance with the License. A copy of the
* License is located 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.
*/
#ifndef CMDLINEPARSER_H_
#define CMDLINEPARSER_H_

#include <map>
#include <string>
#include <vector>

namespace sda {
namespace utils {

bool is_file(const std::string &name);

/*!
 * Synopsis:
 * 1.Parses the command line passed in from the user and stores all enabled
 *      system options.
 * 2.Prints help for the user if an option is not valid.
 * 3.Stores options and provides a mechanism to read those options
 */
class CmdLineParser {
public:
  class CmdSwitch {

  public:
    std::string key;
    std::string shortcut;
    std::string default_value;
    std::string value;
    std::string desc;
    bool istoggle;
    bool isvalid;
  };

public:
  CmdLineParser();
  // CmdLineParser(int argc, char* argv[]);
  virtual ~CmdLineParser();

  bool addSwitch(const CmdSwitch &s);
  bool addSwitch(const std::string &name, const std::string &shortcut,
                 const std::string &desc, const std::string &default_value = "",
                 bool istoggle = false);

  /*!
   * sets default key to be able to read a 2 argumented call
   */
  bool setDefaultKey(const char *key);

  /*!
   * parse and store command line
   */
  int parse(int argc, char *argv[]);

  /*!
   * retrieve value using a key
   */
  std::string value(const char *key);

  int value_to_int(const char *key);

  double value_to_double(const char *key);

  /*!
   * Returns true if a valid value is supplied by user
   */
  bool isValid(const char *key);

  /*!
   * prints the help menu in case the options are not correct.
   */
  virtual void printHelp();

protected:
  /*!
   * Retrieve command switch
   */
  CmdSwitch *getCmdSwitch(const char *key);

  bool token_to_fullkeyname(const std::string &token, std::string &fullkey);

private:
  std::map<std::string, CmdSwitch *> m_mapKeySwitch;
  std::map<std::string, std::string> m_mapShortcutKeys;
  std::vector<CmdSwitch *> m_vSwitches;
  std::string m_strDefaultKey;
  std::string m_appname;
};

// bool starts_with(const string& src, const string& sub);
}
}
#endif /* CMDLINEPARSER_H_ */

