// 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.
#pragma once

#include <cstdint>
#include <iosfwd>
#include <string>

#include "kudu/gutil/endian.h"
#include "kudu/gutil/port.h"
#include "kudu/util/memcmpable_varint.h"
#include "kudu/util/slice.h"

namespace kudu {
class faststring;

// An op timestamp generated by a Clock.
class Timestamp {
 public:
  typedef uint64_t val_type;

  Timestamp() noexcept : v(kInvalidTimestamp.v) {}

  explicit Timestamp(uint64_t val) noexcept : v(val) {}

  // Decode a timestamp from the given input slice.
  // Mutates the slice to point after the decoded timestamp.
  // Returns true upon success.
  bool DecodeFrom(Slice* input);

  // Encode the timestamp to the given buffer.
  void EncodeTo(faststring* dst) const;

  // Returns -1 if this < other.
  // Returns 1 if this > other.
  // Returns 0 if this == other.
  int CompareTo(const Timestamp& other) const;

  std::string ToString() const;

  // Returns this Timestamp as an uint64_t
  uint64_t ToUint64() const;

  // Sets this Timestamp from 'value'
  void FromUint64(uint64_t value);

  val_type value() const { return v; }

  // An initial op timestamp, higher than min so that we can have
  // a Timestamp guaranteed to be lower than all generated timestamps.
  static const Timestamp kInitialTimestamp;

  // An invalid op timestamp -- Timestamp types initialize to this variable.
  static const Timestamp kInvalidTimestamp;

  // The maximum timestamp.
  static const Timestamp kMax;

  // The minimum timestamp.
  static const Timestamp kMin;

 private:
  friend bool operator==(const Timestamp& lhs, const Timestamp& rhs);
  friend bool operator!=(const Timestamp& lhs, const Timestamp& rhs);
  friend bool operator<(const Timestamp& lhs, const Timestamp& rhs);
  friend bool operator<=(const Timestamp& lhs, const Timestamp& rhs);
  friend bool operator>(const Timestamp& lhs, const Timestamp& rhs);
  friend bool operator>=(const Timestamp& lhs, const Timestamp& rhs);

  val_type v;
};

std::ostream& operator<<(std::ostream& o, const Timestamp& timestamp);

inline bool Timestamp::DecodeFrom(Slice* input) {
  // The most common case is that the timestamp is generated from a
  // HybridClock, which will always be encoded as an 8-byte varint.
  // Given this, we can inline fast-path this encoding here and fall
  // back to GetMemcmpableVarint64 only in the rare case of logical
  // clocks used in tests.
  if (PREDICT_TRUE(input->size() >= 9 &&
      (*input)[0] == 0xff)) {
    v = BigEndian::Load64(input->data() + 1);
    input->remove_prefix(9);
    return true;
  }
  return GetMemcmpableVarint64(input, &v);
}

inline int Timestamp::CompareTo(const Timestamp& other) const {
  if (v < other.v) {
    return -1;
  } else if (v > other.v) {
    return 1;
  }
  return 0;
}

inline bool operator==(const Timestamp& lhs, const Timestamp& rhs) {
  return lhs.v == rhs.v;
}

inline bool operator!=(const Timestamp& lhs, const Timestamp& rhs) {
  return !(lhs.v == rhs.v);
}

inline bool operator<(const Timestamp& lhs, const Timestamp& rhs) {
  return lhs.v < rhs.v;
}

inline bool operator>(const Timestamp& lhs, const Timestamp& rhs) {
  return rhs < lhs;
}

inline bool operator<=(const Timestamp& lhs, const Timestamp& rhs) {
  return !(lhs > rhs);
}

inline bool operator>=(const Timestamp& lhs, const Timestamp& rhs) {
  return !(lhs < rhs);
}

} // namespace kudu
