/*
 * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "jfr/recorder/repository/jfrChunk.hpp"
#include "jfr/recorder/repository/jfrChunkWriter.hpp"
#include "jfr/utilities/jfrTime.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.inline.hpp"

static const int64_t MAGIC_OFFSET = 0;
static const int64_t MAGIC_LEN = 4;
static const int64_t VERSION_OFFSET = MAGIC_LEN;
static const int64_t SIZE_OFFSET = 8;
static const int64_t SLOT_SIZE = 8;
static const int64_t CHECKPOINT_OFFSET = SIZE_OFFSET + SLOT_SIZE;
static const int64_t METADATA_OFFSET = CHECKPOINT_OFFSET + SLOT_SIZE;
static const int64_t START_NANOS_OFFSET = METADATA_OFFSET + SLOT_SIZE;
static const int64_t DURATION_NANOS_OFFSET = START_NANOS_OFFSET + SLOT_SIZE;
static const int64_t START_TICKS_OFFSET = DURATION_NANOS_OFFSET + SLOT_SIZE;
static const int64_t CPU_FREQUENCY_OFFSET = START_TICKS_OFFSET + SLOT_SIZE;
static const int64_t GENERATION_OFFSET = CPU_FREQUENCY_OFFSET + SLOT_SIZE;
static const int64_t CAPABILITY_OFFSET = GENERATION_OFFSET + 2;
static const int64_t HEADER_SIZE = CAPABILITY_OFFSET + 2;

static fio_fd open_chunk(const char* path) {
  return path != NULL ? os::open(path, O_CREAT | O_RDWR, S_IREAD | S_IWRITE) : invalid_fd;
}

#ifdef ASSERT
static void assert_writer_position(JfrChunkWriter* writer, int64_t offset) {
  assert(writer != NULL, "invariant");
  assert(offset == writer->current_offset(), "invariant");
}
#endif

class JfrChunkHeadWriter : public StackObj {
 private:
  JfrChunkWriter* _writer;
  JfrChunk* _chunk;
 public:
  void write_magic() {
    _writer->bytes(_chunk->magic(), MAGIC_LEN);
  }

  void write_version() {
    _writer->be_write(_chunk->major_version());
    _writer->be_write(_chunk->minor_version());
  }

  void write_size(int64_t size) {
    _writer->be_write(size);
  }

  void write_checkpoint() {
    _writer->be_write(_chunk->last_checkpoint_offset());
  }

  void write_metadata() {
    _writer->be_write(_chunk->last_metadata_offset());
  }

  void write_time(bool finalize) {
    if (finalize) {
      _writer->be_write(_chunk->previous_start_nanos());
      _writer->be_write(_chunk->last_chunk_duration());
      _writer->be_write(_chunk->previous_start_ticks());
      return;
    }
    _writer->be_write(_chunk->start_nanos());
    _writer->be_write(_chunk->duration());
    _writer->be_write(_chunk->start_ticks());
  }

  void write_cpu_frequency() {
    _writer->be_write(_chunk->cpu_frequency());
  }

  void write_generation(bool finalize) {
    _writer->be_write(finalize ? COMPLETE : _chunk->generation());
    _writer->be_write(PAD);
  }

  void write_next_generation() {
    _writer->be_write(_chunk->next_generation());
    _writer->be_write(PAD);
  }

  void write_guard() {
    _writer->be_write(GUARD);
    _writer->be_write(PAD);
  }

  void write_guard_flush() {
    write_guard();
    _writer->flush();
  }

  void write_capabilities() {
    _writer->be_write(_chunk->capabilities());
  }

  void write_size_to_generation(int64_t size, bool finalize) {
    write_size(size);
    write_checkpoint();
    write_metadata();
    write_time(finalize);
    write_cpu_frequency();
    write_generation(finalize);
  }

  void flush(int64_t size, bool finalize) {
    assert(_writer->is_valid(), "invariant");
    assert(_chunk != NULL, "invariant");
    DEBUG_ONLY(assert_writer_position(_writer, SIZE_OFFSET);)
    write_size_to_generation(size, finalize);
    // no need to write capabilities
    _writer->seek(size); // implicit flush
  }

  void initialize() {
    assert(_writer->is_valid(), "invariant");
    assert(_chunk != NULL, "invariant");
    DEBUG_ONLY(assert_writer_position(_writer, 0);)
    write_magic();
    write_version();
    write_size_to_generation(HEADER_SIZE, false);
    write_capabilities();
    DEBUG_ONLY(assert_writer_position(_writer, HEADER_SIZE);)
    _writer->flush();
  }

  JfrChunkHeadWriter(JfrChunkWriter* writer, int64_t offset, bool guard = true) : _writer(writer), _chunk(writer->_chunk) {
    assert(_writer != NULL, "invariant");
    assert(_writer->is_valid(), "invariant");
    assert(_chunk != NULL, "invariant");
    if (0 == _writer->current_offset()) {
      assert(HEADER_SIZE == offset, "invariant");
      initialize();
    } else {
      if (guard) {
        _writer->seek(GENERATION_OFFSET);
        write_guard();
        _writer->seek(offset);
      } else {
        _chunk->update_current_nanos();
      }
    }
    DEBUG_ONLY(assert_writer_position(_writer, offset);)
  }
};

static int64_t prepare_chunk_header_constant_pool(JfrChunkWriter& cw, int64_t event_offset, bool flushpoint) {
  const int64_t delta = cw.last_checkpoint_offset() == 0 ? 0 : cw.last_checkpoint_offset() - event_offset;
  const u4 checkpoint_type = flushpoint ? (u4)(FLUSH | HEADER) : (u4)HEADER;
  cw.reserve(sizeof(u4));
  cw.write<u8>(EVENT_CHECKPOINT);
  cw.write<u8>(JfrTicks::now().value());
  cw.write<u8>(0); // duration
  cw.write<u8>(delta); // to previous checkpoint
  cw.write<u4>(checkpoint_type);
  cw.write<u4>(1); // pool count
  cw.write<u8>(TYPE_CHUNKHEADER);
  cw.write<u4>(1); // count
  cw.write<u8>(1); // key
  cw.write<u4>(HEADER_SIZE); // length of byte array
  return cw.current_offset();
}

int64_t JfrChunkWriter::write_chunk_header_checkpoint(bool flushpoint) {
  assert(this->has_valid_fd(), "invariant");
  const int64_t event_size_offset = current_offset();
  const int64_t header_content_pos = prepare_chunk_header_constant_pool(*this, event_size_offset, flushpoint);
  JfrChunkHeadWriter head(this, header_content_pos, false);
  head.write_magic();
  head.write_version();
  const int64_t chunk_size_offset = reserve(sizeof(int64_t)); // size to be decided when we are done
  be_write(event_size_offset); // last checkpoint offset will be this checkpoint
  head.write_metadata();
  head.write_time(false);
  head.write_cpu_frequency();
  head.write_next_generation();
  head.write_capabilities();
  assert(current_offset() - header_content_pos == HEADER_SIZE, "invariant");
  const u4 checkpoint_size = current_offset() - event_size_offset;
  write_padded_at_offset<u4>(checkpoint_size, event_size_offset);
  set_last_checkpoint_offset(event_size_offset);
  const size_t sz_written = size_written();
  write_be_at_offset(sz_written, chunk_size_offset);
  return sz_written;
}

int64_t JfrChunkWriter::flush_chunk(bool flushpoint) {
  assert(_chunk != NULL, "invariant");
  const int64_t sz_written = write_chunk_header_checkpoint(flushpoint);
  assert(size_written() == sz_written, "invariant");
  JfrChunkHeadWriter head(this, SIZE_OFFSET);
  head.flush(sz_written, !flushpoint);
  return sz_written;
}

JfrChunkWriter::JfrChunkWriter() : JfrChunkWriterBase(NULL), _chunk(new JfrChunk()) {}

JfrChunkWriter::~JfrChunkWriter() {
  assert(_chunk != NULL, "invariant");
  delete _chunk;
}

void JfrChunkWriter::set_path(const char* path) {
  assert(_chunk != NULL, "invariant");
  _chunk->set_path(path);
}

void JfrChunkWriter::set_time_stamp() {
  assert(_chunk != NULL, "invariant");
  _chunk->set_time_stamp();
}

int64_t JfrChunkWriter::size_written() const {
  return this->is_valid() ? this->current_offset() : 0;
}

int64_t JfrChunkWriter::last_checkpoint_offset() const {
  assert(_chunk != NULL, "invariant");
  return _chunk->last_checkpoint_offset();
}

int64_t JfrChunkWriter::current_chunk_start_nanos() const {
  assert(_chunk != NULL, "invariant");
  return this->is_valid() ? _chunk->start_nanos() : invalid_time;
}

void JfrChunkWriter::set_last_checkpoint_offset(int64_t offset) {
  assert(_chunk != NULL, "invariant");
  _chunk->set_last_checkpoint_offset(offset);
}

void JfrChunkWriter::set_last_metadata_offset(int64_t offset) {
  assert(_chunk != NULL, "invariant");
  _chunk->set_last_metadata_offset(offset);
}

bool JfrChunkWriter::has_metadata() const {
  assert(_chunk != NULL, "invariant");
  return _chunk->has_metadata();
}

bool JfrChunkWriter::open() {
  assert(_chunk != NULL, "invariant");
  JfrChunkWriterBase::reset(open_chunk(_chunk->path()));
  const bool is_open = this->has_valid_fd();
  if (is_open) {
    assert(0 == this->current_offset(), "invariant");
    _chunk->reset();
    JfrChunkHeadWriter head(this, HEADER_SIZE);
  }
  return is_open;
}

int64_t JfrChunkWriter::close() {
  assert(this->has_valid_fd(), "invariant");
  const int64_t size_written = flush_chunk(false);
  this->close_fd();
  assert(!this->is_valid(), "invariant");
  return size_written;
}
