/*
 * 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.solr.client.solrj.cloud.autoscaling;


import java.util.ArrayList;

import org.apache.solr.common.cloud.rule.ImplicitSnitch;
import org.apache.solr.common.util.StrUtils;

import static org.apache.solr.client.solrj.cloud.autoscaling.Clause.parseString;
import static org.apache.solr.client.solrj.cloud.autoscaling.Suggestion.suggestNegativeViolations;
import static org.apache.solr.client.solrj.cloud.autoscaling.Suggestion.suggestPositiveViolations;
import static org.apache.solr.client.solrj.cloud.autoscaling.Variable.Type.FREEDISK;

/**
 *
 * @deprecated to be removed in Solr 9.0 (see SOLR-14656)
 */
public class VariableBase implements Variable {
  final Type varType;

  public VariableBase(Type type) {
    this.varType = type;
  }

  @Override
  public void getSuggestions(Suggestion.Ctx ctx) {
    if (ctx.violation == null) return;
    if (ctx.violation.replicaCountDelta > 0) {
      suggestPositiveViolations(ctx);
    } else {
      suggestNegativeViolations(ctx, ArrayList::new);
    }
  }

  @Override
  public String postValidate(Condition condition) {
    if(Clause.IGNORE_TAGS.contains(condition.getName())) return null;
    if(condition.getOperand() == Operand.WILDCARD && condition.clause.nodeSetPresent){
      return "#EACH not supported in tags in nodeset";
    }
    return null;
  }

  static Object getOperandAdjustedValue(Object val, Object original) {
    if (original instanceof Condition) {
      Condition condition = (Condition) original;
      if (condition.computedType == null && isIntegerEquivalent(val)) {
        if (condition.op == Operand.LESS_THAN) {
          //replica : '<3'
          val = val instanceof Long ?
              (Long) val - 1 :
              (Double) val - 1;
        } else if (condition.op == Operand.GREATER_THAN) {
          //replica : '>4'
          val = val instanceof Long ?
              (Long) val + 1 :
              (Double) val + 1;
        }
      }
    }
    return val;
  }

  static boolean isIntegerEquivalent(Object val) {
    if (val instanceof Number) {
      Number number = (Number) val;
      return Math.ceil(number.doubleValue()) == Math.floor(number.doubleValue());
    } else if (val instanceof String) {
      try {
        double dval = Double.parseDouble((String) val);
        return Math.ceil(dval) == Math.floor(dval);
      } catch (NumberFormatException e) {
        return false;
      }
    } else {
      return false;
    }

  }

  public static Type getTagType(String name) {
    Type info = Type.get(name);
    if (info == null && name.startsWith(ImplicitSnitch.SYSPROP)) info = Type.SYSPROP;
    if (info == null && name.startsWith(Clause.METRICS_PREFIX)) info = Type.LAZY;
    return info;
  }

  @SuppressWarnings({"unchecked"})
  static Variable loadImpl(Meta meta, Type t) {
    @SuppressWarnings({"rawtypes"})
    Class implementation = meta.implementation();
    if (implementation == void.class) implementation = VariableBase.class;
    try {
      return (Variable) implementation.getConstructor(Type.class).newInstance(t);
    } catch (Exception e) {
      throw new RuntimeException("Unable to instantiate: " + implementation.getName(), e);
    }
  }

  @Override
  public int compareViolation(Violation v1, Violation v2) {
    if (v2.replicaCountDelta == null || v1.replicaCountDelta == null) return 0;
    if (Math.abs(v1.replicaCountDelta) == Math.abs(v2.replicaCountDelta)) return 0;
    return Math.abs(v1.replicaCountDelta) < Math.abs(v2.replicaCountDelta) ? -1 : 1;
  }

  @Override
  public Object validate(String name, Object val, boolean isRuleVal) {
    if (val instanceof Condition) {
      Condition condition = (Condition) val;
      val = condition.op.readRuleValue(condition);
      if (val != condition.val) return val;
    }
    if (!isRuleVal && "".equals(val) && this.varType.type != String.class) val = -1;
    if (name == null) name = this.varType.tagName;
    if (varType.type == Double.class) {
      Double num = Clause.parseDouble(name, val);
      if (isRuleVal) {
        if (varType.min != null)
          if (Double.compare(num, varType.min.doubleValue()) == -1)
            throw new RuntimeException(name + ": " + val + " must be greater than " + varType.min);
        if (varType.max != null)
          if (Double.compare(num, varType.max.doubleValue()) == 1)
            throw new RuntimeException(name + ": " + val + " must be less than " + varType.max);
      }
      return num;
    } else if (varType.type == Long.class) {
      Long num = Clause.parseLong(name, val);
      if (isRuleVal) {
        if (varType.min != null)
          if (num < varType.min.longValue())
            throw new RuntimeException(name + ": " + val + " must be greater than " + varType.min);
        if (varType.max != null)
          if (num > varType.max.longValue())
            throw new RuntimeException(name + ": " + val + " must be less than " + varType.max);
      }
      return num;
    } else if (varType.type == String.class) {
      if (isRuleVal && !varType.vals.isEmpty() && !varType.vals.contains(val))
        throw new RuntimeException(name + ": " + val + " must be one of " + StrUtils.join(varType.vals, ','));
      return val;
    } else {
      throw new RuntimeException("Invalid type ");
    }
  }

  public static class TotalDiskVariable extends VariableBase {
    public TotalDiskVariable(Type type) {
      super(type);
    }

    @Override
    public Object convertVal(Object val) {
      return FREEDISK.convertVal(val);
    }
  }

  public static class CoreIndexSizeVariable extends VariableBase {
    public CoreIndexSizeVariable(Type type) {
      super(type);
    }

    @Override
    public Object convertVal(Object val) {
      return FREEDISK.convertVal(val);
    }
  }

  public static class LazyVariable extends VariableBase {
    public LazyVariable(Type type) {
      super(type);
    }

    @Override
    public Object validate(String name, Object val, boolean isRuleVal) {
      return parseString(val);
    }

    @Override
    public boolean match(Object inputVal, Operand op, Object val, String name, Row row) {
      return op.match(parseString(val), parseString(inputVal)) == Clause.TestStatus.PASS;
    }

    @Override
    public void getSuggestions(Suggestion.Ctx ctx) {
      suggestPositiveViolations(ctx);
    }
  }

  public static class DiskTypeVariable extends VariableBase {
    public DiskTypeVariable(Type type) {
      super(type);
    }

    @Override
    public void getSuggestions(Suggestion.Ctx ctx) {
      suggestPositiveViolations(ctx);
    }
  }
}
