/*
 * 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

#ifndef GEODE_TESTOBJECT_PSTOBJECT_H_
#define GEODE_TESTOBJECT_PSTOBJECT_H_

#include <inttypes.h>

#include <string>

#include <ace/ACE.h>
#include <ace/OS.h>
#include <ace/Time_Value.h>

#include <geode/CacheableBuiltins.hpp>

#include "TimestampedObject.hpp"
#include "testobject_export.h"

namespace testobject {

using apache::geode::client::CacheableBytes;
using apache::geode::client::DataInput;
using apache::geode::client::DataOutput;

/**
 * @brief User class for testing the put functionality for object.
 */
class TESTOBJECT_EXPORT PSTObject : public TimestampedObject {
 protected:
  uint64_t timestamp;
  int32_t field1;
  int8_t field2;
  std::shared_ptr<CacheableBytes> valueData;

  inline size_t getObjectSize(const std::shared_ptr<Serializable>& obj) const {
    return (obj == nullptr ? 0 : obj->objectSize());
  }

 public:
  PSTObject() : timestamp(0), valueData(nullptr) {}
  PSTObject(int size, bool encodeKey);
  ~PSTObject() override = default;
  void toData(DataOutput& output) const override;
  void fromData(DataInput& input) override;
  std::string toString() const override;

  size_t objectSize() const override {
    auto objectSize = sizeof(PSTObject);
    objectSize += getObjectSize(valueData);
    return objectSize;
  }

  uint64_t getTimestamp() override { return timestamp; }
  void resetTimestamp() override {
    ACE_Time_Value startTime;
    startTime = ACE_OS::gettimeofday();
    ACE_UINT64 tusec;
    startTime.to_usec(tusec);
    timestamp = tusec * 1000;
  }

  static apache::geode::client::Serializable* createDeserializable() {
    return new PSTObject();
  }
};

}  // namespace testobject

#endif  // GEODE_TESTOBJECT_PSTOBJECT_H_
