// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <trace-reader/reader.h>

#include <inttypes.h>

#include <fbl/string_printf.h>
#include <trace-engine/fields.h>

#include <utility>

namespace trace {

TraceReader::TraceReader(RecordConsumer record_consumer,
                         ErrorHandler error_handler)
    : record_consumer_(std::move(record_consumer)),
      error_handler_(std::move(error_handler)) {
    // Provider ids begin at 1. We don't have a provider yet but we want to
    // set the current provider. So set it to non-existent provider 0.
    RegisterProvider(0u, "");
}

bool TraceReader::ReadRecords(Chunk& chunk) {
    while (true) {
        if (!pending_header_ && !chunk.ReadUint64(&pending_header_))
            return true; // need more data

        auto size = RecordFields::RecordSize::Get<size_t>(pending_header_);
        if (size == 0) {
            ReportError("Unexpected record of size 0");
            return false; // fatal error
        }
        ZX_DEBUG_ASSERT(size <= RecordFields::kMaxRecordSizeWords);

        Chunk record;
        if (!chunk.ReadChunk(size - 1, &record))
            return true; // need more data to decode record

        auto type = RecordFields::Type::Get<RecordType>(pending_header_);
        switch (type) {
        case RecordType::kMetadata: {
            if (!ReadMetadataRecord(record, pending_header_)) {
                ReportError("Failed to read metadata record");
            }
            break;
        }
        case RecordType::kInitialization: {
            if (!ReadInitializationRecord(record, pending_header_)) {
                ReportError("Failed to read initialization record");
            }
            break;
        }
        case RecordType::kString: {
            if (!ReadStringRecord(record, pending_header_)) {
                ReportError("Failed to read string record");
            }
            break;
        }
        case RecordType::kThread: {
            if (!ReadThreadRecord(record, pending_header_)) {
                ReportError("Failed to read thread record");
            }
            break;
        }
        case RecordType::kEvent: {
            if (!ReadEventRecord(record, pending_header_)) {
                ReportError("Failed to read event record");
            }
            break;
        }
        case RecordType::kBlob: {
            void* ptr;
            if (!ReadBlobRecord(record, pending_header_, &ptr)) {
                ReportError("Failed to read blob record");
            }
            break;
        }
        case RecordType::kKernelObject: {
            if (!ReadKernelObjectRecord(record, pending_header_)) {
                ReportError("Failed to read kernel object record");
            }
            break;
        }
        case RecordType::kContextSwitch: {
            if (!ReadContextSwitchRecord(record, pending_header_)) {
                ReportError("Failed to read context switch record");
            }
            break;
        }
        case RecordType::kLog: {
            if (!ReadLogRecord(record, pending_header_)) {
                ReportError("Failed to read log record");
            }
            break;
        }
        default: {
            // Ignore unknown record types for forward compatibility.
            ReportError(fbl::StringPrintf(
                "Skipping record of unknown type %d", static_cast<uint32_t>(type)));
            break;
        }
        }
        pending_header_ = 0u;
    }
}

bool TraceReader::ReadMetadataRecord(Chunk& record, RecordHeader header) {
    auto type = MetadataRecordFields::MetadataType::Get<MetadataType>(header);

    switch (type) {
    case MetadataType::kProviderInfo: {
        auto id = ProviderInfoMetadataRecordFields::Id::Get<ProviderId>(header);
        auto name_length =
            ProviderInfoMetadataRecordFields::NameLength::Get<size_t>(header);
        fbl::StringPiece name_view;
        if (!record.ReadString(name_length, &name_view))
            return false;
        fbl::String name(name_view);

        RegisterProvider(id, name);
        record_consumer_(Record(Record::Metadata{
            MetadataContent(MetadataContent::ProviderInfo{id, name})}));
        break;
    }
    case MetadataType::kProviderSection: {
        auto id =
            ProviderSectionMetadataRecordFields::Id::Get<ProviderId>(header);

        SetCurrentProvider(id);
        record_consumer_(Record(
            Record::Metadata{MetadataContent(MetadataContent::ProviderSection{id})}));
        break;
    }
    case MetadataType::kProviderEvent: {
        auto id =
            ProviderEventMetadataRecordFields::Id::Get<ProviderId>(header);
        auto event = ProviderEventMetadataRecordFields::Event::Get<ProviderEventType>(header);
        switch (event) {
        case ProviderEventType::kBufferOverflow:
            record_consumer_(Record(
                Record::Metadata{MetadataContent(
                    MetadataContent::ProviderEvent{id, event})}));
            break;
        default:
            // Ignore unknown event types for forward compatibility.
            ReportError(fbl::StringPrintf(
                "Skipping provider event of unknown type %u",
                static_cast<unsigned>(event)));
            break;
        }
        break;
    }
    case MetadataType::kTraceInfo: {
        auto info_type = TraceInfoMetadataRecordFields::TraceInfoType::Get<TraceInfoType>(header);
        switch (info_type) {
        case TraceInfoType::kMagicNumber: {
            auto record_magic = MagicNumberRecordFields::Magic::Get<uint32_t>(header);
            record_consumer_(Record(
                Record::Metadata{MetadataContent(
                    MetadataContent::TraceInfo{TraceInfoContent(
                        TraceInfoContent::MagicNumberInfo{record_magic})})}));
            break;
        }
        default: {
            // Ignore unknown trace info types for forward compatibility.
            ReportError(fbl::StringPrintf(
                "Skipping trace info record of unknown type %u",
                static_cast<unsigned>(info_type)));
            break;
        }
        }
        break;
    }
    default: {
        // Ignore unknown metadata types for forward compatibility.
        ReportError(fbl::StringPrintf(
            "Skipping metadata of unknown type %d", static_cast<uint32_t>(type)));
        break;
    }
    }
    return true;
}

bool TraceReader::ReadInitializationRecord(Chunk& record, RecordHeader header) {
    trace_ticks_t ticks_per_second;
    if (!record.ReadUint64(&ticks_per_second) || !ticks_per_second)
        return false;

    record_consumer_(Record(Record::Initialization{ticks_per_second}));
    return true;
}

bool TraceReader::ReadStringRecord(Chunk& record, RecordHeader header) {
    auto index = StringRecordFields::StringIndex::Get<trace_string_index_t>(header);
    if (index < TRACE_ENCODED_STRING_REF_MIN_INDEX ||
        index > TRACE_ENCODED_STRING_REF_MAX_INDEX) {
        ReportError("Invalid string index");
        return false;
    }

    auto length = StringRecordFields::StringLength::Get<size_t>(header);
    fbl::StringPiece string_view;
    if (!record.ReadString(length, &string_view))
        return false;
    fbl::String string(string_view);

    RegisterString(index, string);
    record_consumer_(Record(Record::String{index, std::move(string)}));
    return true;
}

bool TraceReader::ReadThreadRecord(Chunk& record, RecordHeader header) {
    auto index = ThreadRecordFields::ThreadIndex::Get<trace_thread_index_t>(header);
    if (index < TRACE_ENCODED_THREAD_REF_MIN_INDEX ||
        index > TRACE_ENCODED_THREAD_REF_MAX_INDEX) {
        ReportError("Invalid thread index");
        return false;
    }

    zx_koid_t process_koid, thread_koid;
    if (!record.ReadUint64(&process_koid) ||
        !record.ReadUint64(&thread_koid))
        return false;

    ProcessThread process_thread(process_koid, thread_koid);
    RegisterThread(index, process_thread);
    record_consumer_(Record(Record::Thread{index, process_thread}));
    return true;
}

bool TraceReader::ReadEventRecord(Chunk& record, RecordHeader header) {
    auto type = EventRecordFields::EventType::Get<EventType>(header);
    auto argument_count = EventRecordFields::ArgumentCount::Get<size_t>(header);
    auto thread_ref = EventRecordFields::ThreadRef::Get<trace_encoded_thread_ref_t>(header);
    auto category_ref =
        EventRecordFields::CategoryStringRef::Get<trace_encoded_string_ref_t>(header);
    auto name_ref =
        EventRecordFields::NameStringRef::Get<trace_encoded_string_ref_t>(header);

    trace_ticks_t timestamp;
    ProcessThread process_thread;
    fbl::String category;
    fbl::String name;
    fbl::Vector<Argument> arguments;
    if (!record.ReadUint64(&timestamp) ||
        !DecodeThreadRef(record, thread_ref, &process_thread) ||
        !DecodeStringRef(record, category_ref, &category) ||
        !DecodeStringRef(record, name_ref, &name) ||
        !ReadArguments(record, argument_count, &arguments))
        return false;

    switch (type) {
    case EventType::kInstant: {
        uint64_t scope;
        if (!record.ReadUint64(&scope))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments),
            EventData(EventData::Instant{static_cast<EventScope>(scope)})}));
        break;
    }
    case EventType::kCounter: {
        trace_counter_id_t id;
        if (!record.ReadUint64(&id))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::Counter{id})}));
        break;
    }
    case EventType::kDurationBegin: {
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::DurationBegin{})}));
        break;
    }
    case EventType::kDurationEnd: {
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::DurationEnd{})}));
        break;
    }
    case EventType::kDurationComplete: {
        trace_ticks_t end_time;
        if (!record.ReadUint64(&end_time))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::DurationComplete{end_time})}));
        break;
    }
    case EventType::kAsyncBegin: {
        trace_async_id_t id;
        if (!record.ReadUint64(&id))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::AsyncBegin{id})}));
        break;
    }
    case EventType::kAsyncInstant: {
        trace_async_id_t id;
        if (!record.ReadUint64(&id))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::AsyncInstant{id})}));
        break;
    }
    case EventType::kAsyncEnd: {
        trace_async_id_t id;
        if (!record.ReadUint64(&id))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::AsyncEnd{id})}));
        break;
    }
    case EventType::kFlowBegin: {
        trace_flow_id_t id;
        if (!record.ReadUint64(&id))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::FlowBegin{id})}));
        break;
    }
    case EventType::kFlowStep: {
        trace_flow_id_t id;
        if (!record.ReadUint64(&id))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::FlowStep{id})}));
        break;
    }
    case EventType::kFlowEnd: {
        trace_flow_id_t id;
        if (!record.ReadUint64(&id))
            return false;
        record_consumer_(Record(Record::Event{
            timestamp, process_thread, std::move(category), std::move(name),
            std::move(arguments), EventData(EventData::FlowEnd{id})}));
        break;
    }
    default: {
        // Ignore unknown event types for forward compatibility.
        ReportError(fbl::StringPrintf(
            "Skipping event of unknown type %d", static_cast<uint32_t>(type)));
        break;
    }
    }
    return true;
}

bool TraceReader::ReadBlobRecord(Chunk& record, RecordHeader header, void** out_blob) {
    auto blob_type =
        BlobRecordFields::BlobType::Get<trace_blob_type_t>(header);
    auto name_ref =
        BlobRecordFields::NameStringRef::Get<trace_encoded_string_ref_t>(header);
    auto blob_size =
        BlobRecordFields::BlobSize::Get<size_t>(header);
    fbl::String name;
    if (!DecodeStringRef(record, name_ref, &name))
        return false;
    const void* blob;
    auto blob_words = BytesToWords(blob_size);
    if (!record.ReadInPlace(blob_words, &blob))
        return false;

    record_consumer_(
        Record(Record::Blob{blob_type, name, blob, blob_size}));
    return true;
}

bool TraceReader::ReadKernelObjectRecord(Chunk& record, RecordHeader header) {
    auto object_type =
        KernelObjectRecordFields::ObjectType::Get<zx_obj_type_t>(header);
    auto name_ref =
        KernelObjectRecordFields::NameStringRef::Get<trace_encoded_string_ref_t>(header);
    auto argument_count =
        KernelObjectRecordFields::ArgumentCount::Get<size_t>(header);

    zx_koid_t koid;
    fbl::String name;
    fbl::Vector<Argument> arguments;
    if (!record.ReadUint64(&koid) ||
        !DecodeStringRef(record, name_ref, &name) ||
        !ReadArguments(record, argument_count, &arguments))
        return false;

    record_consumer_(
        Record(Record::KernelObject{koid, object_type, name, std::move(arguments)}));
    return true;
}

bool TraceReader::ReadContextSwitchRecord(Chunk& record, RecordHeader header) {
    auto cpu_number =
        ContextSwitchRecordFields::CpuNumber::Get<trace_cpu_number_t>(header);
    auto outgoing_thread_state =
        ContextSwitchRecordFields::OutgoingThreadState::Get<ThreadState>(header);
    auto outgoing_thread_priority =
        ContextSwitchRecordFields::OutgoingThreadPriority::Get<trace_thread_priority_t>(header);
    auto incoming_thread_priority =
        ContextSwitchRecordFields::IncomingThreadPriority::Get<trace_thread_priority_t>(header);
    auto outgoing_thread_ref =
        ContextSwitchRecordFields::OutgoingThreadRef::Get<trace_encoded_thread_ref_t>(
            header);
    auto incoming_thread_ref =
        ContextSwitchRecordFields::IncomingThreadRef::Get<trace_encoded_thread_ref_t>(
            header);

    trace_ticks_t timestamp;
    ProcessThread outgoing_thread;
    ProcessThread incoming_thread;
    if (!record.ReadUint64(&timestamp) ||
        !DecodeThreadRef(record, outgoing_thread_ref,
                         &outgoing_thread) ||
        !DecodeThreadRef(record, incoming_thread_ref, &incoming_thread))
        return false;

    record_consumer_(
        Record(Record::ContextSwitch{timestamp, cpu_number, outgoing_thread_state,
                                     outgoing_thread, incoming_thread,
                                     outgoing_thread_priority, incoming_thread_priority}));
    return true;
}

bool TraceReader::ReadLogRecord(Chunk& record, RecordHeader header) {
    auto log_message_length =
        LogRecordFields::LogMessageLength::Get<uint16_t>(header);

    if (log_message_length > LogRecordFields::kMaxMessageLength)
        return false;

    auto thread_ref = LogRecordFields::ThreadRef::Get<trace_encoded_thread_ref_t>(header);
    trace_ticks_t timestamp;
    ProcessThread process_thread;
    fbl::StringPiece log_message;
    if (!record.ReadUint64(&timestamp) ||
        !DecodeThreadRef(record, thread_ref, &process_thread) ||
        !record.ReadString(log_message_length, &log_message))
        return false;
    record_consumer_(
        Record(Record::Log{timestamp, process_thread, fbl::String(log_message)}));
    return true;
}

bool TraceReader::ReadArguments(Chunk& record,
                                size_t count,
                                fbl::Vector<Argument>* out_arguments) {
    while (count-- > 0) {
        ArgumentHeader header;
        if (!record.ReadUint64(&header)) {
            ReportError("Failed to read argument header");
            return false;
        }

        auto size = ArgumentFields::ArgumentSize::Get<size_t>(header);
        Chunk arg;
        if (!size || !record.ReadChunk(size - 1, &arg)) {
            ReportError("Invalid argument size");
            return false;
        }

        auto name_ref = ArgumentFields::NameRef::Get<trace_encoded_string_ref_t>(header);
        fbl::String name;
        if (!DecodeStringRef(arg, name_ref, &name)) {
            ReportError("Failed to read argument name");
            return false;
        }

        auto type = ArgumentFields::Type::Get<ArgumentType>(header);
        switch (type) {
        case ArgumentType::kNull: {
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakeNull()});
            break;
        }
        case ArgumentType::kBool: {
            auto value = BoolArgumentFields::Value::Get<bool>(header);
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakeBool(value)});
            break;
        }
        case ArgumentType::kInt32: {
            auto value = Int32ArgumentFields::Value::Get<int32_t>(header);
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakeInt32(value)});
            break;
        }
        case ArgumentType::kUint32: {
            auto value = Uint32ArgumentFields::Value::Get<uint32_t>(header);
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakeUint32(value)});
            break;
        }
        case ArgumentType::kInt64: {
            int64_t value;
            if (!arg.ReadInt64(&value)) {
                ReportError("Failed to read int64 argument value");
                return false;
            }
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakeInt64(value)});
            break;
        }
        case ArgumentType::kUint64: {
            uint64_t value;
            if (!arg.ReadUint64(&value)) {
                ReportError("Failed to read uint64 argument value");
                return false;
            }
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakeUint64(value)});
            break;
        }
        case ArgumentType::kDouble: {
            double value;
            if (!arg.ReadDouble(&value)) {
                ReportError("Failed to read double argument value");
                return false;
            }
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakeDouble(value)});
            break;
        }
        case ArgumentType::kString: {
            auto string_ref =
                StringArgumentFields::Index::Get<trace_encoded_string_ref_t>(header);
            fbl::String value;
            if (!DecodeStringRef(arg, string_ref, &value)) {
                ReportError("Failed to read string argument value");
                return false;
            }
            out_arguments->push_back(
                Argument{std::move(name),
                         ArgumentValue::MakeString(std::move(value))});
            break;
        }
        case ArgumentType::kPointer: {
            uint64_t value;
            if (!arg.ReadUint64(&value)) {
                ReportError("Failed to read pointer argument value");
                return false;
            }
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakePointer(value)});
            break;
        }
        case ArgumentType::kKoid: {
            zx_koid_t value;
            if (!arg.ReadUint64(&value)) {
                ReportError("Failed to read koid argument value");
                return false;
            }
            out_arguments->push_back(Argument{std::move(name),
                                              ArgumentValue::MakeKoid(value)});
            break;
        }
        default: {
            // Ignore unknown argument types for forward compatibility.
            ReportError(fbl::StringPrintf(
                "Skipping argument of unknown type %d, argument name %s",
                static_cast<uint32_t>(type), name.c_str()));
            break;
        }
        }
    }
    return true;
}

fbl::String TraceReader::GetProviderName(ProviderId id) const {
    auto it = providers_.find(id);
    if (it != providers_.end())
        return it->name;
    return fbl::String();
}

void TraceReader::SetCurrentProvider(ProviderId id) {
    auto it = providers_.find(id);
    if (it != providers_.end()) {
        current_provider_ = &*it;
        return;
    }
    ReportError(fbl::StringPrintf("Registering non-existent provider %u\n", id));
    RegisterProvider(id, "");
}

void TraceReader::RegisterProvider(ProviderId id, fbl::String name) {
    auto provider = std::make_unique<ProviderInfo>();
    provider->id = id;
    provider->name = name;
    current_provider_ = provider.get();

    providers_.insert_or_replace(std::move(provider));
}

void TraceReader::RegisterString(trace_string_index_t index, fbl::String string) {
    ZX_DEBUG_ASSERT(index >= TRACE_ENCODED_STRING_REF_MIN_INDEX &&
                    index <= TRACE_ENCODED_STRING_REF_MAX_INDEX);

    auto entry = std::make_unique<StringTableEntry>(index, string);
    current_provider_->string_table.insert_or_replace(std::move(entry));
}

void TraceReader::RegisterThread(trace_thread_index_t index,
                                 const ProcessThread& process_thread) {
    ZX_DEBUG_ASSERT(index >= TRACE_ENCODED_THREAD_REF_MIN_INDEX &&
                    index <= TRACE_ENCODED_THREAD_REF_MAX_INDEX);

    auto entry = std::make_unique<ThreadTableEntry>(index, process_thread);
    current_provider_->thread_table.insert_or_replace(std::move(entry));
}

bool TraceReader::DecodeStringRef(Chunk& chunk,
                                  trace_encoded_string_ref_t string_ref,
                                  fbl::String* out_string) const {
    if (string_ref == TRACE_ENCODED_STRING_REF_EMPTY) {
        out_string->clear();
        return true;
    }

    if (string_ref & TRACE_ENCODED_STRING_REF_INLINE_FLAG) {
        size_t length = string_ref & TRACE_ENCODED_STRING_REF_LENGTH_MASK;
        fbl::StringPiece string_view;
        if (length > TRACE_ENCODED_STRING_REF_MAX_LENGTH ||
            !chunk.ReadString(length, &string_view)) {
            ReportError("Could not read inline string");
            return false;
        }
        *out_string = string_view;
        return true;
    }

    auto it = current_provider_->string_table.find(string_ref);
    if (it == current_provider_->string_table.end()) {
        ReportError("String ref not in table");
        return false;
    }
    *out_string = it->string;
    return true;
}

bool TraceReader::DecodeThreadRef(Chunk& chunk,
                                  trace_encoded_thread_ref_t thread_ref,
                                  ProcessThread* out_process_thread) const {
    if (thread_ref == TRACE_ENCODED_THREAD_REF_INLINE) {
        zx_koid_t process_koid, thread_koid;
        if (!chunk.ReadUint64(&process_koid) ||
            !chunk.ReadUint64(&thread_koid)) {
            ReportError("Could not read inline process and thread");
            return false;
        }
        *out_process_thread = ProcessThread(process_koid, thread_koid);
        return true;
    }

    auto it = current_provider_->thread_table.find(thread_ref);
    if (it == current_provider_->thread_table.end()) {
        ReportError(fbl::StringPrintf("Thread ref 0x%x not in table",
                                      thread_ref));
        return false;
    }
    *out_process_thread = it->process_thread;
    return true;
}

void TraceReader::ReportError(fbl::String error) const {
    if (error_handler_)
        error_handler_(std::move(error));
}

Chunk::Chunk()
    : begin_(nullptr), current_(nullptr), end_(nullptr) {}

Chunk::Chunk(const uint64_t* begin, size_t num_words)
    : begin_(begin), current_(begin), end_(begin_ + num_words) {}

bool Chunk::ReadUint64(uint64_t* out_value) {
    if (current_ < end_) {
        *out_value = *current_++;
        return true;
    }
    return false;
}

bool Chunk::ReadInt64(int64_t* out_value) {
    if (current_ < end_) {
        *out_value = *reinterpret_cast<const int64_t*>(current_++);
        return true;
    }
    return false;
}

bool Chunk::ReadDouble(double* out_value) {
    if (current_ < end_) {
        *out_value = *reinterpret_cast<const double*>(current_++);
        return true;
    }
    return false;
}

bool Chunk::ReadChunk(size_t num_words, Chunk* out_chunk) {
    if (current_ + num_words > end_)
        return false;

    *out_chunk = Chunk(current_, num_words);
    current_ += num_words;
    return true;
}

bool Chunk::ReadString(size_t length, fbl::StringPiece* out_string) {
    auto num_words = BytesToWords(length);
    if (current_ + num_words > end_)
        return false;

    *out_string =
        fbl::StringPiece(reinterpret_cast<const char*>(current_), length);
    current_ += num_words;
    return true;
}

bool Chunk::ReadInPlace(size_t num_words, const void** out_ptr) {
    if (current_ + num_words > end_)
        return false;
    *out_ptr = current_;
    current_ += num_words;
    return true;
}

} // namespace trace
