// Path: src/main/java/net/nandgr/cba/custom/model/Rules.java
// public class Rules {
// 
//   private List<Rule> rules;
// 
//   public List<Rule> getRules() {
//     return rules;
//   }
// 
//   public void setRules(List<Rule> rules) {
//     this.rules = rules;
//   }
// 
//   @Override
//   public String toString() {
//     return "Rules{" +
//             "rules=" + Arrays.toString(rules.toArray()) +
//             '}';
//   }
// 
//   public void validateRules() throws BadRulesException {
//     for (Rule rule : this.getRules()) {
//       if (StringUtils.isBlank(rule.getName())) {
//         throw new BadRulesException("Rule name cannot be blank.");
//       }
//       validateRule(rule);
//     }
//   }
// 
//   private static void validateRule(Rule rule) throws BadRulesException {
//     if (rule.getInvocations() != null) {
//       for (Invocation invocation : rule.getInvocations()) {
// 
//         Method notFrom = invocation.getNotFrom();
//         checkEmpty(notFrom, "\"invocation.notFrom\" property cannot have all the fields blank.");
// 
//         Method from = invocation.getFrom();
//         checkEmpty(from, "\"invocation.from\" property cannot have all the fields blank.");
// 
//         Method method = invocation.getMethod();
//         checkEmpty(method, "\"invocation.method\" property cannot have all the fields blank.");
// 
//         if (notFrom != null && from != null) {
//           throw new BadRulesException("\"invocation.notFrom\" and \"invocation.from\" cannot be defined at the same time in the same rule.");
//         }
//       }
//     }
//   }
// 
//   private static void checkEmpty(Method method, String message) throws BadRulesException {
//     if (allEmpty(method)) {
//       throw new BadRulesException(message);
//     }
//   }
// }
// 
// Path: src/main/java/net/nandgr/cba/exception/BadArgumentsException.java
// public class BadArgumentsException extends Exception {
// 
//   public BadArgumentsException(String message) {
//     super(message);
//   }
// 
//   public BadArgumentsException(String message, Throwable cause) {
//     super(message, cause);
//   }
// }
// 
// Path: src/main/java/net/nandgr/cba/exception/BadRulesException.java
// public class BadRulesException extends Exception {
// 
//   public BadRulesException(String message) {
//     super(message);
//   }
// }
// 
// Path: src/main/java/net/nandgr/cba/logging/LogHelper.java
// public class LogHelper {
// 
//   private LogHelper() {
//     throw new IllegalAccessError("Cannot instantiate this utility class.");
//   }
//   public static void toDebug() {
//     Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
//     root.setLevel(Level.DEBUG);
//   }
// 
//   public static void toTrace() {
//     Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
//     root.setLevel(Level.TRACE);
//   }
// }


import com.google.gson.Gson;
import java.io.File;
import java.io.IOException;
import net.nandgr.cba.custom.model.Rules;
import net.nandgr.cba.exception.BadArgumentsException;
import net.nandgr.cba.exception.BadRulesException;
import net.nandgr.cba.logging.LogHelper;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
    Option verboseDebug = Option
            .builder("v")
            .longOpt("verbose-debug")
            .desc("Increase verbosity to debug mode.")
            .build();

    Option verboseTrace = Option
            .builder("vv")
            .longOpt("verbose-trace")
            .desc("Increase verbosity to trace mode  - makes it slower, use it only when you need.")
            .build();

    options.addOption(help);
    options.addOption(path);
    /*
    disabled until thread safety is done properly.
    options.addOption(maxThreads);
    */
    options.addOption(maxReportItems);
    options.addOption(output);
    options.addOption(checks);
    options.addOption(customFile);
    options.addOption(verboseDebug);
    options.addOption(verboseTrace);
  }

  public static Options getOptions() {
    return options;
  }

// Path: src/main/java/net/nandgr/cba/custom/model/Rules.java
// public class Rules {
// 
//   private List<Rule> rules;
// 
//   public List<Rule> getRules() {
//     return rules;
//   }
// 
//   public void setRules(List<Rule> rules) {
//     this.rules = rules;
//   }
// 
//   @Override
//   public String toString() {
//     return "Rules{" +
//             "rules=" + Arrays.toString(rules.toArray()) +
//             '}';
//   }
// 
//   public void validateRules() throws BadRulesException {
//     for (Rule rule : this.getRules()) {
//       if (StringUtils.isBlank(rule.getName())) {
//         throw new BadRulesException("Rule name cannot be blank.");
//       }
//       validateRule(rule);
//     }
//   }
// 
//   private static void validateRule(Rule rule) throws BadRulesException {
//     if (rule.getInvocations() != null) {
//       for (Invocation invocation : rule.getInvocations()) {
// 
//         Method notFrom = invocation.getNotFrom();
//         checkEmpty(notFrom, "\"invocation.notFrom\" property cannot have all the fields blank.");
// 
//         Method from = invocation.getFrom();
//         checkEmpty(from, "\"invocation.from\" property cannot have all the fields blank.");
// 
//         Method method = invocation.getMethod();
//         checkEmpty(method, "\"invocation.method\" property cannot have all the fields blank.");
// 
//         if (notFrom != null && from != null) {
//           throw new BadRulesException("\"invocation.notFrom\" and \"invocation.from\" cannot be defined at the same time in the same rule.");
//         }
//       }
//     }
//   }
// 
//   private static void checkEmpty(Method method, String message) throws BadRulesException {
//     if (allEmpty(method)) {
//       throw new BadRulesException(message);
//     }
//   }
// }
// 
// Path: src/main/java/net/nandgr/cba/exception/BadArgumentsException.java
// public class BadArgumentsException extends Exception {
// 
//   public BadArgumentsException(String message) {
//     super(message);
//   }
// 
//   public BadArgumentsException(String message, Throwable cause) {
//     super(message, cause);
//   }
// }
// 
// Path: src/main/java/net/nandgr/cba/exception/BadRulesException.java
// public class BadRulesException extends Exception {
// 
//   public BadRulesException(String message) {
//     super(message);
//   }
// }
// 
// Path: src/main/java/net/nandgr/cba/logging/LogHelper.java
// public class LogHelper {
// 
//   private LogHelper() {
//     throw new IllegalAccessError("Cannot instantiate this utility class.");
//   }
//   public static void toDebug() {
//     Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
//     root.setLevel(Level.DEBUG);
//   }
// 
//   public static void toTrace() {
//     Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
//     root.setLevel(Level.TRACE);
//   }
// }


// Path: src/main/java/net/nandgr/cba/cli/CliArguments.java
import com.google.gson.Gson;
import java.io.File;
import java.io.IOException;
import net.nandgr.cba.custom.model.Rules;
import net.nandgr.cba.exception.BadArgumentsException;
import net.nandgr.cba.exception.BadRulesException;
import net.nandgr.cba.logging.LogHelper;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

    Option verboseDebug = Option
            .builder("v")
            .longOpt("verbose-debug")
            .desc("Increase verbosity to debug mode.")
            .build();

    Option verboseTrace = Option
            .builder("vv")
            .longOpt("verbose-trace")
            .desc("Increase verbosity to trace mode  - makes it slower, use it only when you need.")
            .build();

    options.addOption(help);
    options.addOption(path);
    /*
    disabled until thread safety is done properly.
    options.addOption(maxThreads);
    */
    options.addOption(maxReportItems);
    options.addOption(output);
    options.addOption(checks);
    options.addOption(customFile);
    options.addOption(verboseDebug);
    options.addOption(verboseTrace);
  }

  public static Options getOptions() {
    return options;
  }

  public static void parseArguments(String[] args) throws BadArgumentsException {