// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vdslib.state;

import java.util.ArrayList;

/**
 *
 * Defines legal states for various uses. Split this into its own class such
 * that we can easily see what states are legal to use in what situations.
 * They double as disk states and node states nodes report they are in, and
 * wanted states set external sources.
 */
public enum State {

    // The order declares the ordinals, and defines what states are above/below others
    UNKNOWN     ("-", false, true,  true,  false, false, false, false, false), // This state is used by the fleetcontroller to indicate
                                                                               // that we have failed to contact the node. It should never be
                                                                               // sent out of the fleetcontroller
    MAINTENANCE ("m", false, false, false, true,  true,  false, true,  true),
    DOWN        ("d", true,  true,  true,  true,  true,  true,  true,  true), // Down is not valid reported state sent from the node itself.
    STOPPING    ("s", false, true,  true,  false, false, true,  true,  true),
    INITIALIZING("i", false, true,  true,  false, false, true,  true,  true),
    RETIRED     ("r", false, false, false, false, true,  false, true,  true),
    UP          ("u", true,  true,  true,  true,  true,  true,  true,  true);

    private final boolean validDiskState;
    private final boolean validClusterState;
    private final ArrayList<Boolean> validReportedNodeState = new ArrayList<>();
    private final ArrayList<Boolean> validWantedNodeState = new ArrayList<>();
    private final ArrayList<Boolean> validCurrentNodeState = new ArrayList<>();
    private final String serializedAs;

    private State(String serialized, boolean validDisk, boolean validDistReported, boolean validStorReported,
                  boolean validDistWanted, boolean validStorWanted, boolean validCluster, boolean validDistCurrent,
                  boolean validStorCurrent)
    {
        validDiskState = validDisk;
        validClusterState = validCluster;
        assert(NodeType.STORAGE.ordinal() == 0);
        assert(NodeType.DISTRIBUTOR.ordinal() == 1);
        validReportedNodeState.add(validStorReported);
        validReportedNodeState.add(validDistReported);
        validWantedNodeState.add(validStorWanted);
        validWantedNodeState.add(validDistWanted);
        validCurrentNodeState.add(validStorCurrent);
        validCurrentNodeState.add(validDistCurrent);
        this.serializedAs = serialized;
    }

    public static State get(String serialized) {
        for (State s : values()) {
            if (s.serializedAs.equals(serialized)) { return s; }
        }
        throw new IllegalArgumentException("Invalid state '" + serialized + "'.");
    }

    public String serialize() { return serializedAs; }

    public boolean validDiskState() { return validDiskState; }
    public boolean validClusterState() { return validClusterState; }
    public boolean validReportedNodeState(NodeType type) { return validReportedNodeState.get(type.ordinal()); }
    public boolean validWantedNodeState(NodeType type) { return validWantedNodeState.get(type.ordinal()); }
    public boolean validCurrentNodeState(NodeType type) { return validCurrentNodeState.get(type.ordinal()); }

    public boolean maySetWantedStateForThisNodeState(State s) { return (s.ordinal() <= ordinal()); }

    public boolean oneOf(String states) {
        for (char c : states.toCharArray()) {
            String s = "" + c;
            if (s.equals(serializedAs)) return true;
        }
        return false;
    }

    @Override
    public String toString() {
        String id = name();
        String lower = id.substring(1).toLowerCase();
        return id.charAt(0) + lower;
    }

}

@@ -567,37 +567,28 @@
    (%22-%22,
- false,
  true,
- 
  true,
- 
  false, 
@@ -743,25 +743,16 @@
         
-         
 // that 
@@ -876,25 +876,16 @@
         
-    
-     
 // sent 
@@ -946,37 +946,28 @@
 , false,
- false,
  true,
- 
  true,
- 
  false, 
@@ -963,33 +963,32 @@
 ue, false, true,
- 
  true),%0A    DOWN
@@ -1010,51 +1010,38 @@
 rue,
- 
  true,
- 
  true,
- 
  true,
- 
  true,
- 
  true,
-  true, 
  tru
@@ -1128,37 +1128,28 @@
    (%22s%22,
- false,
  true,
- 
  true,
- 
  false, 
@@ -1156,32 +1156,30 @@
 false, true,
- 
  true,
- 
  true),%0A    
@@ -1195,37 +1195,28 @@
 ING(%22i%22,
- false,
  true,
- 
  true,
- 
  false, 
@@ -1223,32 +1223,30 @@
 false, true,
- 
  true,
- 
  true),%0A    
@@ -1283,30 +1283,22 @@
 , false,
- false,
  true,
- 
  false, 
@@ -1298,25 +1298,24 @@
 false, true,
- 
  true),%0A    
@@ -1341,101 +1341,46 @@
 rue,
- 
  true,
- 
  true,
- 
  true,
- 
  true,
- 
  true, 
- true,  true);%0A%0A    private final boolean validDiskState;
+true);%0A
 %0A   
@@ -1705,24 +1705,16 @@
 s;%0A%0A    
-private 
 State(St
@@ -1733,27 +1733,8 @@
 zed,
- boolean validDisk,
  boo
@@ -1783,34 +1783,16 @@
 eported,
-%0A                 
  boolean
@@ -1804,24 +1804,34 @@
 dDistWanted,
+%0A         
  boolean val
@@ -1891,34 +1891,16 @@
 Current,
-%0A                 
  boolean
@@ -1917,20 +1917,16 @@
 Current)
-%0A   
  %7B%0A     
@@ -1937,173 +1937,35 @@
 alid
-DiskState = validDisk;%0A        validClusterState = validCluster;%0A        assert(NodeType.STORAGE.ordinal() == 0);%0A        assert(NodeType.DISTRIBUTOR.ordinal() == 1)
+ClusterState = validCluster
 ;%0A  
@@ -2636,71 +2636,8 @@
  %7D%0A%0A
-    public boolean validDiskState() %7B return validDiskState; %7D%0A
     

Remove validDiskState, not used