/*
 * 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.htrace.core;

import java.util.concurrent.ThreadLocalRandom;

/**
 * Uniquely identifies an HTrace span.
 *
 * Span IDs are 128 bits in total.  The upper 64 bits of a span ID is the same
 * as the upper 64 bits of the parent span, if there is one.  The lower 64 bits
 * are always random.
 */
public final class SpanId implements Comparable<SpanId> {
  private static final int SPAN_ID_STRING_LENGTH = 32;
  private final long high;
  private final long low;

  /**
   * The invalid span ID, which is all zeroes.
   *
   * It is also the "least" span ID in the sense that it is considered
   * smaller than any other span ID.
   */
  public static SpanId INVALID = new SpanId(0, 0);

  private static long nonZeroRand64() {
    while (true) {
      long r = ThreadLocalRandom.current().nextLong();
      if (r != 0) {
        return r;
      }
    }
  }

  public static SpanId fromRandom() {
    return new SpanId(nonZeroRand64(), nonZeroRand64());
  }

  public static SpanId fromString(String str) {
    if (str.length() != SPAN_ID_STRING_LENGTH) {
      throw new RuntimeException("Invalid SpanID string: length was not " +
          SPAN_ID_STRING_LENGTH);
    }
    long high =
      ((Long.parseLong(str.substring(0, 8), 16)) << 32) |
      (Long.parseLong(str.substring(8, 16), 16));
    long low =
      ((Long.parseLong(str.substring(16, 24), 16)) << 32) |
      (Long.parseLong(str.substring(24, 32), 16));
    return new SpanId(high, low);
  }

  public SpanId(long high, long low) {
    this.high = high;
    this.low = low;
  }

  public long getHigh() {
    return high;
  }

  public long getLow() {
    return low;
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof SpanId)) {
      return false;
    }
    SpanId other = (SpanId)o;
    return ((other.high == high) && (other.low == low));
  }

  @Override
  public int compareTo(SpanId other) {
    int cmp = compareAsUnsigned(high, other.high);
    if (cmp != 0) {
      return cmp;
    }
    return compareAsUnsigned(low, other.low);
  }

  private static int compareAsUnsigned(long a, long b) {
    boolean aSign = a < 0;
    boolean bSign = b < 0;
    if (aSign != bSign) {
      if (aSign) {
        return 1;
      } else {
        return -1;
      }
    }
    if (aSign) {
      a = -a;
      b = -b;
    }
    if (a < b) {
      return -1;
    } else if (a > b) {
      return 1;
    } else {
      return 0;
    }
  }

  @Override
  public int hashCode() {
    return (int)((0xffffffff & (high >> 32))) ^
           (int)((0xffffffff & (high >> 0))) ^
           (int)((0xffffffff & (low >> 32))) ^
           (int)((0xffffffff & (low >> 0)));
  }

  @Override
  public String toString() {
    return String.format("%08x%08x%08x%08x",
        (0x00000000ffffffffL & (high >> 32)),
        (0x00000000ffffffffL & high),
        (0x00000000ffffffffL & (low >> 32)),
        (0x00000000ffffffffL & low));
  }

  public boolean isValid() {
    return (high != 0)  || (low != 0);
  }

  public SpanId newChildId() {
    return new SpanId(high, nonZeroRand64());
  }
}
