/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License 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.
 */

package org.apache.geode.management.internal.cli.commands;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

import org.apache.logging.log4j.Logger;
import org.springframework.shell.core.annotation.CliCommand;

import org.apache.geode.annotations.Immutable;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.JndiBindingsType;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.management.cli.GfshCommand;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
import org.apache.geode.management.internal.cli.functions.ListJndiBindingFunction;
import org.apache.geode.management.internal.cli.result.model.ResultModel;
import org.apache.geode.management.internal.cli.result.model.TabularResultModel;
import org.apache.geode.management.internal.security.ResourceOperation;
import org.apache.geode.security.ResourcePermission;

public class ListJndiBindingCommand extends GfshCommand {
  private static final Logger logger = LogService.getLogger();

  public static final String LIST_JNDIBINDING = "list jndi-binding";
  private static final String LIST_JNDIBINDING__HELP =
      "List all jndi bindings, active and configured. An active binding is one that is bound to the server's jndi context (and also listed in the cluster config). A configured binding is one that is listed in the cluster config, but may not be active on the servers.";
  @Immutable
  private static final Function LIST_BINDING_FUNCTION = new ListJndiBindingFunction();

  @CliCommand(value = LIST_JNDIBINDING, help = LIST_JNDIBINDING__HELP)
  @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
      operation = ResourcePermission.Operation.READ)
  public ResultModel listJndiBinding() {
    ResultModel resultModel = new ResultModel();
    TabularResultModel configTable = null;

    InternalConfigurationPersistenceService ccService =
        (InternalConfigurationPersistenceService) getConfigurationPersistenceService();
    if (ccService != null) {
      configTable = resultModel.addTable("clusterConfiguration");
      // we don't support creating jndi binding with random group name yet
      CacheConfig cacheConfig = ccService.getCacheConfig("cluster");
      List<JndiBindingsType.JndiBinding> jndiBindings = cacheConfig.getJndiBindings();
      if (jndiBindings.size() == 0) {
        configTable.setHeader("No JNDI-bindings found in cluster configuration");
      } else {
        configTable.setHeader("Configured JNDI bindings: ");
        for (JndiBindingsType.JndiBinding jndiBinding : jndiBindings) {
          configTable.accumulate("Group Name", "cluster");
          configTable.accumulate("JNDI Name", jndiBinding.getJndiName());
          configTable.accumulate("JDBC Driver Class", jndiBinding.getJdbcDriverClass());
        }
      }
    }

    Set<DistributedMember> members = findMembers(null, null);

    if (members.size() == 0) {
      if (configTable == null) {
        return ResultModel.createError("No members found");
      }
      configTable.setFooter("No members found");
      return resultModel;
    }

    TabularResultModel memberTable = resultModel.addTable("memberConfiguration");
    List<CliFunctionResult> rc = executeAndGetFunctionResult(LIST_BINDING_FUNCTION, null, members);

    memberTable.setHeader("Active JNDI bindings found on each member: ");
    for (CliFunctionResult oneResult : rc) {
      Serializable[] serializables = oneResult.getSerializables();
      for (int i = 0; i < serializables.length; i += 2) {
        memberTable.accumulate("Member", oneResult.getMemberIdOrName());
        memberTable.accumulate("JNDI Name", (String) serializables[i]);
        memberTable.accumulate("JDBC Driver Class", (String) serializables[i + 1]);
      }
    }
    return resultModel;
  }
}
