/*
 * 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.slider.providers.agent;

import org.apache.slider.providers.agent.application.metadata.CommandOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Stores the command dependency order for all components in a service. <commandOrder>
 * <command>SUPERVISOR-START</command> <requires>NIMBUS-STARTED</requires> </commandOrder> Means, SUPERVISOR START
 * requires NIMBUS to be STARTED
 */
public class ComponentCommandOrder {
  public static final Logger log =
      LoggerFactory.getLogger(ComponentCommandOrder.class);
  private static char SPLIT_CHAR = '-';
  Map<Command, Map<String, List<ComponentState>>> dependencies = new HashMap<>();

  public ComponentCommandOrder(List<CommandOrder> commandOrders) {
    if (commandOrders != null && commandOrders.size() > 0) {
      for (CommandOrder commandOrder : commandOrders) {
        ComponentCommand componentCmd = getComponentCommand(commandOrder.getCommand());
        String requires = commandOrder.getRequires();
        List<ComponentState> requiredStates = parseRequiredStates(requires);
        if (requiredStates.size() > 0) {
          Map<String, List<ComponentState>> compDep = dependencies.get(componentCmd.command);
          if (compDep == null) {
            compDep = new HashMap<>();
            dependencies.put(componentCmd.command, compDep);
          }

          List<ComponentState> requirements = compDep.get(componentCmd.componentName);
          if (requirements == null) {
            requirements = new ArrayList<>();
            compDep.put(componentCmd.componentName, requirements);
          }

          requirements.addAll(requiredStates);
        }
      }
    }
  }

  private List<ComponentState> parseRequiredStates(String requires) {
    if (requires == null || requires.length() < 2) {
      throw new IllegalArgumentException("Input cannot be null and must contain component and state.");
    }

    String[] componentStates = requires.split(",");
    List<ComponentState> retList = new ArrayList<>();
    for (String componentStateStr : componentStates) {
      retList.add(getComponentState(componentStateStr));
    }

    return retList;
  }

  private ComponentCommand getComponentCommand(String compCmdStr) {
    if (compCmdStr == null || compCmdStr.trim().length() < 2) {
      throw new IllegalArgumentException("Input cannot be null and must contain component and command.");
    }

    compCmdStr = compCmdStr.trim();
    int splitIndex = compCmdStr.lastIndexOf(SPLIT_CHAR);
    if (splitIndex == -1 || splitIndex == 0 || splitIndex == compCmdStr.length() - 1) {
      throw new IllegalArgumentException("Input does not appear to be well-formed.");
    }
    String compStr = compCmdStr.substring(0, splitIndex);
    String cmdStr = compCmdStr.substring(splitIndex + 1);

    Command cmd = Command.valueOf(cmdStr);

    if (cmd != Command.START) {
      throw new IllegalArgumentException("Dependency order can only be specified for START.");
    }
    return new ComponentCommand(compStr, cmd);
  }

  private ComponentState getComponentState(String compStStr) {
    if (compStStr == null || compStStr.trim().length() < 2) {
      throw new IllegalArgumentException("Input cannot be null.");
    }

    compStStr = compStStr.trim();
    int splitIndex = compStStr.lastIndexOf(SPLIT_CHAR);
    if (splitIndex == -1 || splitIndex == 0 || splitIndex == compStStr.length() - 1) {
      throw new IllegalArgumentException("Input does not appear to be well-formed.");
    }
    String compStr = compStStr.substring(0, splitIndex);
    String stateStr = compStStr.substring(splitIndex + 1);

    State state = State.valueOf(stateStr);
    if (state != State.STARTED && state != State.INSTALLED) {
      throw new IllegalArgumentException("Dependency order can only be specified against STARTED/INSTALLED.");
    }
    return new ComponentState(compStr, state);
  }

  public boolean canExecute(String component, Command command, Collection<ComponentInstanceState> currentStates) {
    boolean canExecute = true;
    if (dependencies.containsKey(command) && dependencies.get(command).containsKey(component)) {
      List<ComponentState> required = dependencies.get(command).get(component);
      for (ComponentState stateToMatch : required) {
        for (ComponentInstanceState currState : currentStates) {
          log.debug("Checking schedule {} {} against dependency {} is {}",
                    component, command, currState.getCompName(), currState.getState());
          if (currState.getCompName().equals(stateToMatch.componentName)) {
            if (currState.getState() != stateToMatch.state) {
              if (stateToMatch.state == State.STARTED) {
                log.info("Cannot schedule {} {} as dependency {} is {}",
                         component, command, currState.getCompName(), currState.getState());
                canExecute = false;
              } else {
                //state is INSTALLED
                if (currState.getState() != State.STARTING && currState.getState() != State.STARTED) {
                  log.info("Cannot schedule {} {} as dependency {} is {}",
                           component, command, currState.getCompName(), currState.getState());
                  canExecute = false;
                }
              }
            }
          }
          if (!canExecute) {
            break;
          }
        }
        if (!canExecute) {
          break;
        }
      }
    }

    return canExecute;
  }

  static class ComponentState {
    public String componentName;
    public State state;

    public ComponentState(String componentName, State state) {
      this.componentName = componentName;
      this.state = state;
    }
  }

  static class ComponentCommand {
    public String componentName;
    public Command command;

    public ComponentCommand(String componentName, Command command) {
      this.componentName = componentName;
      this.command = command;
    }
  }
}
