/**
   * Creates a CLI script for adding Security-Domain to AS7
   *
   * @param securityDomain object representing migrated security-domain
   * @return created string containing the CLI script for adding the Security-Domain
   * @throws CliScriptException if required attributes are missing
   */
  private static String createSecurityDomainScript(SecurityDomainBean securityDomain)
      throws CliScriptException {
    String errMsg = " in security-domain must be set.";
    Utils.throwIfBlank(securityDomain.getSecurityDomainName(), errMsg, "Security name");

    CliAddScriptBuilder builder = new CliAddScriptBuilder();
    StringBuilder resultScript = new StringBuilder("/subsystem=security/security-domain=");

    resultScript.append(securityDomain.getSecurityDomainName()).append(":add(");
    builder.addProperty("cache-type", securityDomain.getCacheType());

    resultScript.append(builder.asString()).append(")");

    return resultScript.toString();
  }
  /**
   * Creates a CLI script for adding a Login-Module of the specific Security-Domain
   *
   * @param domain Security-Domain containing Login-Module
   * @param module Login-Module
   * @return created string containing the CLI script for adding the Login-Module
   */
  private static String createLoginModuleScript(
      SecurityDomainBean domain, LoginModuleAS7Bean module) {
    StringBuilder resultScript =
        new StringBuilder("/subsystem=security/security-domain=" + domain.getSecurityDomainName());
    resultScript.append("/authentication=classic:add(login-modules=[{");

    if ((module.getLoginModuleCode() != null) && !(module.getLoginModuleCode().isEmpty())) {
      resultScript.append("\"code\"=>\"").append(module.getLoginModuleCode()).append("\"");
    }
    if ((module.getLoginModuleFlag() != null) && !(module.getLoginModuleFlag().isEmpty())) {
      resultScript.append(", \"flag\"=>\"").append(module.getLoginModuleFlag()).append("\"");
    }

    if ((module.getModuleOptions() != null) && !(module.getModuleOptions().isEmpty())) {
      StringBuilder modulesBuilder = new StringBuilder();
      for (ModuleOptionAS7Bean moduleOptionAS7 : module.getModuleOptions()) {
        modulesBuilder.append(", (\"").append(moduleOptionAS7.getModuleOptionName()).append("\"=>");
        modulesBuilder.append("\"").append(moduleOptionAS7.getModuleOptionValue()).append("\")");
      }

      String modules = modulesBuilder.toString().replaceFirst(",", "");
      modules = modules.replaceFirst(" ", "");

      if (!modules.isEmpty()) {
        resultScript.append(", \"module-option\"=>[").append(modules).append("]");
      }
    }

    return resultScript.toString();
  }
  /**
   * Creates CliCommandAction for adding a Login-Module of the specific Security-Domain
   *
   * @param domain Security-Domain containing Login-Module
   * @param module Login-Module
   * @return created CliCommandAction for adding the Login-Module
   */
  public static CliCommandAction createLoginModuleCliAction(
      SecurityDomainBean domain, LoginModuleAS7Bean module) {
    ModelNode request = new ModelNode();
    request.get(ClientConstants.OP).set(ClientConstants.ADD);
    request.get(ClientConstants.OP_ADDR).add("subsystem", "security");
    request.get(ClientConstants.OP_ADDR).add("security-domain", domain.getSecurityDomainName());
    request.get(ClientConstants.OP_ADDR).add("authentication", "classic");

    ModelNode moduleNode = new ModelNode();
    ModelNode list = new ModelNode();

    if (module.getModuleOptions() != null) {
      ModelNode optionNode = new ModelNode();
      for (ModuleOptionAS7Bean option : module.getModuleOptions()) {
        optionNode.get(option.getModuleOptionName()).set(option.getModuleOptionValue());
      }
      moduleNode.get("module-options").set(optionNode);
    }

    CliApiCommandBuilder builder = new CliApiCommandBuilder(moduleNode);
    builder.addProperty("flag", module.getLoginModuleFlag());
    builder.addProperty("code", module.getLoginModuleCode());

    // Needed for CLI because parameter login-modules requires LIST
    list.add(builder.getCommand());

    request.get("login-modules").set(list);

    return new CliCommandAction(
        SecurityMigrator.class, createLoginModuleScript(domain, module), request);
  }
  /**
   * Migrates application-policy from AS5 to AS7
   *
   * @param appPolicy object representing application-policy
   * @param ctx migration context
   * @return created security-domain
   */
  public SecurityDomainBean migrateAppPolicy(
      ApplicationPolicyBean appPolicy, MigrationContext ctx) {
    Set<LoginModuleAS7Bean> loginModules = new HashSet();
    SecurityDomainBean securityDomain = new SecurityDomainBean();

    securityDomain.setSecurityDomainName(appPolicy.getApplicationPolicyName());
    securityDomain.setCacheType("default");
    if (appPolicy.getLoginModules() != null) {
      for (LoginModuleAS5Bean lmAS5 : appPolicy.getLoginModules()) {
        loginModules.add(createLoginModule(lmAS5));
      }
    }

    securityDomain.setLoginModules(loginModules);

    return securityDomain;
  }
  /**
   * Creates a list of CliCommandActions for adding a Security-Domain
   *
   * @param domain Security-Domain
   * @return created list containing CliCommandActions for adding the Security-Domain
   * @throws CliScriptException if required attributes for a creation of the CLI command of the
   *     Security-Domain are missing or are empty (security-domain-name)
   */
  public static List<CliCommandAction> createSecurityDomainCliAction(SecurityDomainBean domain)
      throws CliScriptException {
    String errMsg = " in security-domain must be set.";
    Utils.throwIfBlank(domain.getSecurityDomainName(), errMsg, "Security name");

    List<CliCommandAction> actions = new ArrayList();

    ModelNode domainCmd = new ModelNode();
    domainCmd.get(ClientConstants.OP).set(ClientConstants.ADD);
    domainCmd.get(ClientConstants.OP_ADDR).add("subsystem", "security");
    domainCmd.get(ClientConstants.OP_ADDR).add("security-domain", domain.getSecurityDomainName());

    actions.add(
        new CliCommandAction(
            SecurityMigrator.class, createSecurityDomainScript(domain), domainCmd));

    if (domain.getLoginModules() != null) {
      for (LoginModuleAS7Bean module : domain.getLoginModules()) {
        actions.add(createLoginModuleCliAction(domain, module));
      }
    }

    return actions;
  }