/**
   * Creates a list of CliCommandActions for adding a Connector
   *
   * @param connAS7 Connector
   * @return created list containing CliCommandActions for adding the Connector
   * @throws CliScriptException if required attributes for a creation of the CLI command of the
   *     Connector are missing or are empty (socket-binding, connector-name, protocol)
   */
  private static List<CliCommandAction> createConnectorCliAction(ConnectorAS7Bean connAS7)
      throws CliScriptException {
    String errMsg = " in connector must be set.";
    Utils.throwIfBlank(connAS7.getScheme(), errMsg, "Scheme");
    Utils.throwIfBlank(connAS7.getSocketBinding(), errMsg, "Socket-binding");
    Utils.throwIfBlank(connAS7.getConnectorName(), errMsg, "Connector name");
    Utils.throwIfBlank(connAS7.getProtocol(), errMsg, "Protocol");

    List<CliCommandAction> actions = new LinkedList();

    actions.add(
        new CliCommandAction(
            ServerMigrator.class,
            createConnectorScript(connAS7),
            createConnectorModelNode(connAS7)));

    if (connAS7.getScheme().equals("https")) {
      actions.add(
          new CliCommandAction(
              ServerMigrator.class, createSSLConfScript(connAS7), createSSLConfModelNode(connAS7)));
    }

    return actions;
  }
  /**
   * Creates a CLI script for adding a SSL configuration of the Connector
   *
   * @param connAS7 Connector containing SSL configuration
   * @return created string containing the CLI script for adding the SSL configuration
   * @deprecated Generate this from the ModelNode.
   */
  private static String createSSLConfScript(ConnectorAS7Bean connAS7) {
    CliAddScriptBuilder builder = new CliAddScriptBuilder();
    StringBuilder resultScript =
        new StringBuilder("/subsystem=web/connector=" + connAS7.getConnectorName());

    resultScript.append("/ssl=configuration:add(");

    builder.addProperty("name", connAS7.getSslName());
    builder.addProperty("verify-client", connAS7.getVerifyClient());
    builder.addProperty("verify-depth", connAS7.getVerifyDepth());
    builder.addProperty("certificate-key-file", connAS7.getCertifKeyFile());
    builder.addProperty("password", connAS7.getPassword());
    builder.addProperty("protocol", connAS7.getProtocol());
    builder.addProperty("ciphers", connAS7.getCiphers());
    builder.addProperty("key-alias", connAS7.getKeyAlias());
    builder.addProperty("ca-certificate-file", connAS7.getCaCertifFile());
    builder.addProperty("session-cache-size", connAS7.getSessionCacheSize());
    builder.addProperty("session-timeout", connAS7.getSessionTimeout());

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

    return resultScript.toString();
  }
  /**
   * Creates a CLI script for adding a Connector
   *
   * @param connAS7 object of migrated connector
   * @return string containing created CLI script
   * @throws CliScriptException if required attributes are missing
   * @deprecated Generate this from the ModelNode.
   */
  private static String createConnectorScript(ConnectorAS7Bean connAS7) throws CliScriptException {
    String errMsg = " in connector must be set.";
    Utils.throwIfBlank(connAS7.getScheme(), errMsg, "Scheme");
    Utils.throwIfBlank(connAS7.getSocketBinding(), errMsg, "Socket-binding");
    Utils.throwIfBlank(connAS7.getConnectorName(), errMsg, "Connector name");
    Utils.throwIfBlank(connAS7.getProtocol(), errMsg, "Protocol");

    CliAddScriptBuilder builder = new CliAddScriptBuilder();
    StringBuilder resultScript = new StringBuilder("/subsystem=web/connector=");

    resultScript.append(connAS7.getConnectorName()).append(":add(");

    builder.addProperty("socket-binding", connAS7.getSocketBinding());
    builder.addProperty("enable-lookups", connAS7.getEnableLookups());
    builder.addProperty("max-post-size", connAS7.getMaxPostSize());
    builder.addProperty("max-save-post-size", connAS7.getMaxSavePostSize());
    builder.addProperty("max-connections", connAS7.getMaxConnections());
    builder.addProperty("protocol", connAS7.getProtocol());
    builder.addProperty("proxy-name", connAS7.getProxyName());
    builder.addProperty("proxy-port", connAS7.getProxyPort());
    builder.addProperty("redirect-port", connAS7.getRedirectPort());
    builder.addProperty("scheme", connAS7.getScheme());
    builder.addProperty("secure", connAS7.getSecure());
    builder.addProperty("enabled", connAS7.getEnabled());

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

    return resultScript.toString();
  }
  private static ModelNode createSSLConfModelNode(ConnectorAS7Bean connAS7) {
    ModelNode sslConf = new ModelNode();
    sslConf.get(ClientConstants.OP).set(ClientConstants.ADD);
    sslConf.get(ClientConstants.OP_ADDR).add("subsystem", "web");
    sslConf.get(ClientConstants.OP_ADDR).add("connector", connAS7.getConnectorName());
    sslConf.get(ClientConstants.OP_ADDR).add("ssl", "configuration");

    CliApiCommandBuilder sslBuilder = new CliApiCommandBuilder(sslConf);

    sslBuilder.addProperty("name", connAS7.getSslName());
    sslBuilder.addProperty("verify-client", connAS7.getVerifyClient());
    sslBuilder.addProperty("verify-depth", connAS7.getVerifyDepth());
    sslBuilder.addProperty("certificate-key-file", connAS7.getCertifKeyFile());
    sslBuilder.addProperty("password", connAS7.getPassword());
    sslBuilder.addProperty("protocol", connAS7.getProtocol());
    sslBuilder.addProperty("ciphers", connAS7.getCiphers());
    sslBuilder.addProperty("key-alias", connAS7.getKeyAlias());
    sslBuilder.addProperty("ca-certificate-file", connAS7.getCaCertifFile());
    sslBuilder.addProperty("session-cache-size", connAS7.getSessionCacheSize());
    sslBuilder.addProperty("session-timeout", connAS7.getSessionTimeout());
    return sslBuilder.getCommand();
  }
  private static ModelNode createConnectorModelNode(ConnectorAS7Bean connAS7) {
    ModelNode connCmd = new ModelNode();
    connCmd.get(ClientConstants.OP).set(ClientConstants.ADD);
    connCmd.get(ClientConstants.OP_ADDR).add("subsystem", "web");
    connCmd.get(ClientConstants.OP_ADDR).add("connector", connAS7.getConnectorName());

    CliApiCommandBuilder builder = new CliApiCommandBuilder(connCmd);

    builder.addProperty("socket-binding", connAS7.getSocketBinding());
    builder.addProperty("enable-lookups", connAS7.getEnableLookups());
    builder.addProperty("max-post-size", connAS7.getMaxPostSize());
    builder.addProperty("max-save-post-size", connAS7.getMaxSavePostSize());
    builder.addProperty("max-connections", connAS7.getMaxConnections());
    builder.addProperty("protocol", connAS7.getProtocol());
    builder.addProperty("proxy-name", connAS7.getProxyName());
    builder.addProperty("proxy-port", connAS7.getProxyPort());
    builder.addProperty("redirect-port", connAS7.getRedirectPort());
    builder.addProperty("scheme", connAS7.getScheme());
    builder.addProperty("secure", connAS7.getSecure());
    builder.addProperty("enabled", connAS7.getEnabled());
    return builder.getCommand();
  }
  /**
   * Migrates a connector from AS5 to AS7
   *
   * @param connector object representing connector in AS5
   * @return migrated AS7's connector
   * @throws NodeGenerationException if socket-binding cannot be created or set
   */
  private ConnectorAS7Bean migrateConnector(
      ConnectorAS5Bean connector, ServerMigratorResource resource, MigrationContext ctx)
      throws NodeGenerationException {
    ConnectorAS7Bean connAS7 = new ConnectorAS7Bean();

    connAS7.setEnabled("true");
    connAS7.setEnableLookups(connector.getEnableLookups());
    connAS7.setMaxPostSize(connector.getMaxPostSize());
    connAS7.setMaxSavePostSize(connector.getMaxSavePostSize());
    connAS7.setProtocol(connector.getProtocol());
    connAS7.setProxyName(connector.getProxyName());
    connAS7.setProxyPort(connector.getProxyPort());
    connAS7.setRedirectPort(connector.getRedirectPort());

    // Ajp connector need scheme too. So http is set.
    connAS7.setScheme("http");

    // Socket-binding
    String protocol = null;
    if (connector.getProtocol().equals("HTTP/1.1")) {
      protocol = "true".equalsIgnoreCase(connector.getSslEnabled()) ? "https" : "http";
    } else {
      // TODO: This can't be just assumed!
      protocol = "ajp";
    }
    connAS7.setSocketBinding(createSocketBinding(connector.getPort(), protocol, resource));

    // Name
    connAS7.setConnectorName(protocol);

    // SSL enabled?
    if ("true".equalsIgnoreCase(connector.getSslEnabled())) {
      connAS7.setScheme("https");
      connAS7.setSecure(connector.getSecure());

      connAS7.setSslName("ssl");
      connAS7.setVerifyClient(connector.getClientAuth());

      if (connector.getKeystoreFile() != null) {
        String fName = new File(connector.getKeystoreFile()).getName();
        connAS7.setCertifKeyFile(AS7_CONFIG_DIR_PLACEHOLDER + "/keys/" + fName);
        CopyFileAction action = createCopyActionForKeyFile(resource, fName);
        if (action != null) ctx.getActions().add(action);
      }

      // TODO: No sure which protocols can be in AS5.
      if ((connector.getSslProtocol().equals("TLS")) || (connector.getSslProtocol() == null)) {
        connAS7.setSslProtocol("TLSv1");
      } else {
        connAS7.setSslProtocol(connector.getSslProtocol());
      }

      connAS7.setCiphers(connector.getCiphers());
      connAS7.setKeyAlias(connAS7.getKeyAlias());

      // TODO: AS 7 has just one password, while AS 5 has keystorePass and truststorePass.
      connAS7.setPassword(connector.getKeystorePass());
    }

    return connAS7;
  }