/*
 * 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.internal.serialization;

import java.util.Arrays;
import java.util.stream.Collectors;

import org.apache.geode.annotations.Immutable;

/**
 * Enumerated type for client / server and p2p version.
 *
 * There are dependencies in versioning code that require newer versions to have ordinals higher
 * than older versions in order to protect against deserialization problems. Client/server code also
 * uses greater-than comparison of ordinals in backward-compatibility checks.
 *
 * @since GemFire 5.7
 */
@Immutable
public class KnownVersion extends AbstractVersion {

  /** The name of this version */
  private final transient String name;

  /** The product name of this version */
  private final transient String productName;

  /** The suffix to use in toDataPre / fromDataPre method names */
  private final transient String methodSuffix;

  // the major, minor and release bits of the release
  private final byte majorVersion;
  private final byte minorVersion;
  private final byte release;
  private final byte patch;

  public static final int HIGHEST_VERSION = 125;

  @Immutable
  private static final KnownVersion[] VALUES = new KnownVersion[HIGHEST_VERSION + 1];

  /**
   * Reserved token that cannot be used for product version but as a flag in internal contexts.
   */
  static final byte TOKEN_ORDINAL = -1;
  static final int TOKEN_ORDINAL_INT = (TOKEN_ORDINAL & 0xFF);

  @Immutable
  public static final KnownVersion TOKEN =
      new KnownVersion("", "TOKEN", (byte) -1, (byte) 0, (byte) 0, (byte) 0, TOKEN_ORDINAL);

  private static final short GFE_56_ORDINAL = 0;

  @Immutable
  public static final KnownVersion GFE_56 =
      new KnownVersion("GFE", "5.6", (byte) 5, (byte) 6, (byte) 0, (byte) 0, GFE_56_ORDINAL);

  private static final short GFE_57_ORDINAL = 1;

  @Immutable
  public static final KnownVersion GFE_57 =
      new KnownVersion("GFE", "5.7", (byte) 5, (byte) 7, (byte) 0, (byte) 0, GFE_57_ORDINAL);

  private static final short GFE_58_ORDINAL = 3;

  @Immutable
  public static final KnownVersion GFE_58 =
      new KnownVersion("GFE", "5.8", (byte) 5, (byte) 8, (byte) 0, (byte) 0, GFE_58_ORDINAL);

  private static final short GFE_603_ORDINAL = 4;

  @Immutable
  public static final KnownVersion GFE_603 =
      new KnownVersion("GFE", "6.0.3", (byte) 6, (byte) 0, (byte) 3, (byte) 0, GFE_603_ORDINAL);

  private static final short GFE_61_ORDINAL = 5;

  @Immutable
  public static final KnownVersion GFE_61 =
      new KnownVersion("GFE", "6.1", (byte) 6, (byte) 1, (byte) 0, (byte) 0, GFE_61_ORDINAL);

  private static final short GFE_65_ORDINAL = 6;

  @Immutable
  public static final KnownVersion GFE_65 =
      new KnownVersion("GFE", "6.5", (byte) 6, (byte) 5, (byte) 0, (byte) 0, GFE_65_ORDINAL);

  private static final short GFE_651_ORDINAL = 7;

  @Immutable
  public static final KnownVersion GFE_651 =
      new KnownVersion("GFE", "6.5.1", (byte) 6, (byte) 5, (byte) 1, (byte) 0, GFE_651_ORDINAL);

  private static final short GFE_6516_ORDINAL = 12;

  @Immutable
  public static final KnownVersion GFE_6516 =
      new KnownVersion("GFE", "6.5.1.6", (byte) 6, (byte) 5, (byte) 1, (byte) 6, GFE_6516_ORDINAL);

  private static final short GFE_66_ORDINAL = 16;

  @Immutable
  public static final KnownVersion GFE_66 =
      new KnownVersion("GFE", "6.6", (byte) 6, (byte) 6, (byte) 0, (byte) 0, GFE_66_ORDINAL);

  private static final short GFE_662_ORDINAL = 17;

  @Immutable
  public static final KnownVersion GFE_662 =
      new KnownVersion("GFE", "6.6.2", (byte) 6, (byte) 6, (byte) 2, (byte) 0, GFE_662_ORDINAL);

  private static final short GFE_6622_ORDINAL = 18;

  @Immutable
  public static final KnownVersion GFE_6622 =
      new KnownVersion("GFE", "6.6.2.2", (byte) 6, (byte) 6, (byte) 2, (byte) 2, GFE_6622_ORDINAL);

  private static final short GFE_70_ORDINAL = 19;

  @Immutable
  public static final KnownVersion GFE_70 =
      new KnownVersion("GFE", "7.0", (byte) 7, (byte) 0, (byte) 0, (byte) 0, GFE_70_ORDINAL);

  private static final short GFE_701_ORDINAL = 20;

  @Immutable
  public static final KnownVersion GFE_701 =
      new KnownVersion("GFE", "7.0.1", (byte) 7, (byte) 0, (byte) 1, (byte) 0, GFE_701_ORDINAL);

  private static final short GFE_7099_ORDINAL = 21;

  @Immutable
  public static final KnownVersion GFE_7099 =
      new KnownVersion("GFE", "7.0.99", (byte) 7, (byte) 0, (byte) 99, (byte) 0, GFE_7099_ORDINAL);

  private static final short GFE_71_ORDINAL = 22;

  @Immutable
  public static final KnownVersion GFE_71 =
      new KnownVersion("GFE", "7.1", (byte) 7, (byte) 1, (byte) 0, (byte) 0, GFE_71_ORDINAL);

  // 23-29 available for 7.x variants

  private static final short GFE_80_ORDINAL = 30;

  @Immutable
  public static final KnownVersion GFE_80 =
      new KnownVersion("GFE", "8.0", (byte) 8, (byte) 0, (byte) 0, (byte) 0, GFE_80_ORDINAL);

  // 31-34 available for 8.0.x variants

  private static final short GFE_8009_ORDINAL = 31;

  @Immutable
  public static final KnownVersion GFE_8009 =
      new KnownVersion("GFE", "8.0.0.9", (byte) 8, (byte) 0, (byte) 0, (byte) 9, GFE_8009_ORDINAL);

  private static final short GFE_81_ORDINAL = 35;

  @Immutable
  public static final KnownVersion GFE_81 =
      new KnownVersion("GFE", "8.1", (byte) 8, (byte) 1, (byte) 0, (byte) 0, GFE_81_ORDINAL);

  // 36-39 available for 8.1.x variants

  private static final short GFE_82_ORDINAL = 40;

  @Immutable
  public static final KnownVersion GFE_82 =
      new KnownVersion("GFE", "8.2", (byte) 8, (byte) 2, (byte) 0, (byte) 0, GFE_82_ORDINAL);

  // 41-44 available for 8.2.x variants

  private static final short GFE_90_ORDINAL = 45; // this is also GEODE 1.0.0-incubating

  @Immutable
  public static final KnownVersion GFE_90 =
      new KnownVersion("GFE", "9.0", (byte) 9, (byte) 0, (byte) 0, (byte) 0, GFE_90_ORDINAL);

  // prior to v1.2.0 GEODE_1_1_0 was named GFE_91. This was used for both the rel/v1.1.0
  // and rel/v1.1.1 releases
  private static final short GEODE_1_1_0_ORDINAL = 50;

  @Immutable
  public static final KnownVersion GEODE_1_1_0 =
      new KnownVersion("GEODE", "1.1.0", (byte) 1, (byte) 1, (byte) 0, (byte) 0,
          GEODE_1_1_0_ORDINAL);

  // This ordinal was never used
  private static final short GEODE_1_1_1_ORDINAL = 55;

  @Immutable
  public static final KnownVersion GEODE_1_1_1 =
      new KnownVersion("GEODE", "1.1.1", (byte) 1, (byte) 1, (byte) 1, (byte) 0,
          GEODE_1_1_1_ORDINAL);

  private static final short GEODE_1_2_0_ORDINAL = 65;

  @Immutable
  public static final KnownVersion GEODE_1_2_0 =
      new KnownVersion("GEODE", "1.2.0", (byte) 1, (byte) 2, (byte) 0, (byte) 0,
          GEODE_1_2_0_ORDINAL);

  private static final short GEODE_1_3_0_ORDINAL = 70;

  @Immutable
  public static final KnownVersion GEODE_1_3_0 =
      new KnownVersion("GEODE", "1.3.0", (byte) 1, (byte) 3, (byte) 0, (byte) 0,
          GEODE_1_3_0_ORDINAL);

  private static final short GEODE_1_4_0_ORDINAL = 75;

  @Immutable
  public static final KnownVersion GEODE_1_4_0 =
      new KnownVersion("GEODE", "1.4.0", (byte) 1, (byte) 4, (byte) 0, (byte) 0,
          GEODE_1_4_0_ORDINAL);

  private static final short GEODE_1_5_0_ORDINAL = 80;

  @Immutable
  public static final KnownVersion GEODE_1_5_0 =
      new KnownVersion("GEODE", "1.5.0", (byte) 1, (byte) 5, (byte) 0, (byte) 0,
          GEODE_1_5_0_ORDINAL);

  private static final short GEODE_1_6_0_ORDINAL = 85;

  @Immutable
  public static final KnownVersion GEODE_1_6_0 =
      new KnownVersion("GEODE", "1.6.0", (byte) 1, (byte) 6, (byte) 0, (byte) 0,
          GEODE_1_6_0_ORDINAL);

  private static final short GEODE_1_7_0_ORDINAL = 90;

  @Immutable
  public static final KnownVersion GEODE_1_7_0 =
      new KnownVersion("GEODE", "1.7.0", (byte) 1, (byte) 7, (byte) 0, (byte) 0,
          GEODE_1_7_0_ORDINAL);

  private static final short GEODE_1_8_0_ORDINAL = 95;

  @Immutable
  public static final KnownVersion GEODE_1_8_0 =
      new KnownVersion("GEODE", "1.8.0", (byte) 1, (byte) 8, (byte) 0, (byte) 0,
          GEODE_1_8_0_ORDINAL);

  private static final short GEODE_1_9_0_ORDINAL = 100;

  @Immutable
  public static final KnownVersion GEODE_1_9_0 =
      new KnownVersion("GEODE", "1.9.0", (byte) 1, (byte) 9, (byte) 0, (byte) 0,
          GEODE_1_9_0_ORDINAL);


  private static final byte GEODE_1_10_0_ORDINAL = 105;

  @Immutable
  public static final KnownVersion GEODE_1_10_0 =
      new KnownVersion("GEODE", "1.10.0", (byte) 1, (byte) 10, (byte) 0, (byte) 0,
          GEODE_1_10_0_ORDINAL);

  private static final short GEODE_1_11_0_ORDINAL = 110;

  @Immutable
  public static final KnownVersion GEODE_1_11_0 =
      new KnownVersion("GEODE", "1.11.0", (byte) 1, (byte) 11, (byte) 0, (byte) 0,
          GEODE_1_11_0_ORDINAL);

  private static final short GEODE_1_12_0_ORDINAL = 115;

  @Immutable
  public static final KnownVersion GEODE_1_12_0 =
      new KnownVersion("GEODE", "1.12.0", (byte) 1, (byte) 12, (byte) 0, (byte) 0,
          GEODE_1_12_0_ORDINAL);

  private static final short GEODE_1_12_1_ORDINAL = 116;

  @Immutable
  public static final KnownVersion GEODE_1_12_1 =
      new KnownVersion("GEODE", "1.12.1", (byte) 1, (byte) 12, (byte) 1, (byte) 0,
          GEODE_1_12_1_ORDINAL);

  private static final short GEODE_1_13_0_ORDINAL = 120;

  @Immutable
  public static final KnownVersion GEODE_1_13_0 =
      new KnownVersion("GEODE", "1.13.0", (byte) 1, (byte) 13, (byte) 0, (byte) 0,
          GEODE_1_13_0_ORDINAL);

  private static final short GEODE_1_13_1_ORDINAL = 121;

  @Immutable
  public static final KnownVersion GEODE_1_13_1 =
      new KnownVersion("GEODE", "1.13.1", (byte) 1, (byte) 13, (byte) 1, (byte) 0,
          GEODE_1_13_1_ORDINAL);

  private static final short GEODE_1_14_0_ORDINAL = 125;

  @Immutable
  public static final KnownVersion GEODE_1_14_0 =
      new KnownVersion("GEODE", "1.14.0", (byte) 1, (byte) 14, (byte) 0, (byte) 0,
          GEODE_1_14_0_ORDINAL);

  /* NOTE: when adding a new version bump the ordinal by 5. Ordinals can be short ints */

  /**
   * This constant must be set to the most current version of the product. !!! NOTE: update
   * HIGHEST_VERSION when changing CURRENT !!!
   */
  @Immutable
  public static final KnownVersion CURRENT = GEODE_1_14_0;

  /**
   * A lot of versioning code needs access to the current version's ordinal
   */
  @Immutable
  public static final short CURRENT_ORDINAL = CURRENT.ordinal();

  /**
   * version ordinal for test Backward compatibility.
   */
  private static final short validOrdinalForTesting = 2;

  @Immutable
  public static final KnownVersion TEST_VERSION =
      new KnownVersion("TEST", "VERSION", (byte) 0, (byte) 0,
          (byte) 0, (byte) 0, validOrdinalForTesting);

  /** Creates a new instance of <code>Version</code> */
  private KnownVersion(String product, String name, byte major, byte minor, byte release,
      byte patch,
      short ordinal) {
    super(ordinal);
    this.productName = product;
    this.name = name;
    this.majorVersion = major;
    this.minorVersion = minor;
    this.release = release;
    this.patch = patch;
    this.methodSuffix = this.productName + "_" + this.majorVersion + "_" + this.minorVersion + "_"
        + this.release + "_" + this.patch;
    if (ordinal != TOKEN_ORDINAL) {
      VALUES[ordinal()] = this;
    }
  }

  public static KnownVersion getCurrentVersion() {
    return CURRENT;
  }

  public static String unsupportedVersionMessage(final short ordinal) {
    return String.format(
        "Peer or client version with ordinal %s not supported. Highest known version is %s",
        ordinal, CURRENT.name);
  }

  public String getMethodSuffix() {
    return this.methodSuffix;
  }

  public String getName() {
    return this.name;
  }

  public short getMajorVersion() {
    return this.majorVersion;
  }

  public short getMinorVersion() {
    return this.minorVersion;
  }

  public short getRelease() {
    return this.release;
  }

  public short getPatch() {
    return this.patch;
  }

  /**
   * Returns a string representation for this <code>Version</code>.
   *
   * @return the name of this operation.
   */
  @Override
  public String toString() {
    return this.productName + " " + this.name;
  }

  public byte[] toBytes() {
    byte[] bytes = new byte[2];
    bytes[0] = (byte) (ordinal() >> 8);
    bytes[1] = (byte) ordinal();
    return bytes;
  }

  public static Iterable<? extends KnownVersion> getAllVersions() {
    return Arrays.asList(VALUES).stream().filter(x -> x != null && x != TEST_VERSION)
        .collect(Collectors.toList());
  }

  /**
   * package-protected for use by Versioning factory
   */
  static KnownVersion getKnownVersionOrDefault(final short ordinal,
      final KnownVersion defaultKnownVersion) {
    if (ordinal == TOKEN_ORDINAL) {
      return TOKEN;
    }
    if (ordinal < TOKEN_ORDINAL || ordinal >= VALUES.length || VALUES[ordinal] == null) {
      return defaultKnownVersion;
    }
    return VALUES[ordinal];
  }

}
