// Copyright 2017 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 <lib/edid/edid.h>
#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "eisa_vid_lut.h"

namespace {

template<typename T> bool base_validate(const T* block) {
    static_assert(sizeof(T) == edid::kBlockSize, "Size check for Edid struct");

    const uint8_t* edid_bytes = reinterpret_cast<const uint8_t*>(block);
    if (edid_bytes[0] != T::kTag) {
        return false;
    }

    // The last byte of the 128-byte EDID data is a checksum byte which
    // should make the 128 bytes sum to zero.
    uint8_t sum = 0;
    for (uint32_t i = 0; i < edid::kBlockSize; ++i) {
        sum = static_cast<uint8_t>(sum + edid_bytes[i]);
    }
    return sum == 0;
}

uint32_t round_div(double num, double div) {
    return (uint32_t) ((num / div) + .5);
}

} // namespace

namespace edid {

bool BaseEdid::validate() const {
    static const uint8_t kEdidHeader[8] = {0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0};
    return base_validate<BaseEdid>(this) && memcmp(header, kEdidHeader, sizeof(kEdidHeader)) == 0;
}

bool CeaEdidTimingExtension::validate() const {
    if (!(dtd_start_idx <= sizeof(payload) && base_validate<CeaEdidTimingExtension>(this))) {
        return false;
    }
    size_t offset = 0;
    size_t dbc_end = dtd_start_idx - offsetof(CeaEdidTimingExtension, payload);
    while (offset < dbc_end) {
        const DataBlock* data_block = reinterpret_cast<const DataBlock*>(payload + offset);
        offset += (1 + data_block->length()); // Length doesn't include the header
        // Check that the block doesn't run past the end if the dbc
        if (offset > dbc_end) {
            return false;
        }
    }
    return true;
}

bool Edid::Init(void* ctx, ddc_i2c_transact transact, const char** err_msg) {
    uint8_t segment_address = 0;
    uint8_t segment_offset = 0;
    ddc_i2c_msg_t msgs[3] = {
        { .is_read = false, .addr = kDdcSegmentI2cAddress, .buf = &segment_address, .length = 1 },
        { .is_read = false, .addr = kDdcDataI2cAddress, .buf = &segment_offset, .length = 1 },
        { .is_read = true, .addr = kDdcDataI2cAddress, .buf = nullptr, .length = kBlockSize },
    };

    BaseEdid base_edid;
    msgs[2].buf = reinterpret_cast<uint8_t*>(&base_edid);
    // + 1 to skip trying to set the segment for the first block
    if (!transact(ctx, msgs + 1, 2)) {
        *err_msg = "Failed to read base edid";
        return false;
    } else if (!base_edid.validate()) {
        *err_msg = "Failed to validate base edid";
        return false;
    }

    uint16_t edid_length = static_cast<uint16_t>((base_edid.num_extensions + 1) * kBlockSize);
    fbl::AllocChecker ac;
    edid_bytes_ = fbl::unique_ptr<uint8_t[]>(new (&ac) uint8_t[edid_length]);
    if (!ac.check()) {
        *err_msg = "Failed to allocate edid storage";
        return false;
    }

    memcpy(edid_bytes_.get(), reinterpret_cast<void*>(&base_edid), kBlockSize);
    for (uint8_t i = 1; i && i <= base_edid.num_extensions; i++) {
        *msgs[0].buf = i / 2;
        *msgs[1].buf = i % 2 ? kBlockSize : 0;
        msgs[2].buf = edid_bytes_.get() + i * kBlockSize;
        bool include_segment = i % 2;
        if (!transact(ctx, msgs + include_segment, 3 - include_segment)) {
            *err_msg = "Failed to read full edid";
            return false;
        }
    }

    return Init(edid_bytes_.get(), edid_length, err_msg);
}

bool Edid::Init(const uint8_t* bytes, uint16_t len, const char** err_msg) {
    // The maximum size of an edid is 255 * 128 bytes, so any 16 bit multiple is fine.
    if (len == 0 || len % kBlockSize != 0) {
        *err_msg = "Invalid edid length";
        return false;
    }
    bytes_ = bytes;
    len_ = len;
    if (!(base_edid_ = GetBlock<BaseEdid>(0)) || !base_edid_->validate()) {
        *err_msg = "Failed to validate base edid";
        return false;
    }
    if (((base_edid_->num_extensions + 1) * kBlockSize) != len) {
        *err_msg = "Bad extension count";
        return false;
    }
    if (!base_edid_->digital()) {
        *err_msg = "Analog displays not supported";
        return false;
    }

    for (uint8_t i = 1; i < len / kBlockSize; i++) {
        if (bytes_[i * kBlockSize] == CeaEdidTimingExtension::kTag) {
            if (!GetBlock<CeaEdidTimingExtension>(i)->validate()) {
                *err_msg = "Failed to validate extensions";
                return false;
            }
        }
    }

    monitor_serial_[0] = monitor_name_[0] = '\0';
    for (auto it = descriptor_iterator(this); it.is_valid(); ++it) {
        char* dest;
        if (it->timing.pixel_clock_10khz != 0) {
            continue;
        } else if (it->monitor.type == Descriptor::Monitor::kName) {
            dest = monitor_name_;
        } else if (it->monitor.type == Descriptor::Monitor::kSerial) {
            dest = monitor_serial_;
        } else {
            continue;
        }

        uint32_t len;
        for (len = 0;
                len < sizeof(Descriptor::Monitor::data) && it->monitor.data[len] != 0x0A;
                ++len) {
            // Empty body
        }

        snprintf(dest, len + 1, "%s", it->monitor.data);
    }

    // If we didn't find a valid serial descriptor, use the base serial number
    if (monitor_serial_[0] == '\0') {
        sprintf(monitor_serial_, "%d", base_edid_->serial_number);
    }

    uint8_t c1 = static_cast<uint8_t>(((base_edid_->manufacturer_id1 & 0x7c) >> 2) + 'A' - 1);
    uint8_t c2 = static_cast<uint8_t>((((base_edid_->manufacturer_id1 & 0x03) << 3)
            | (base_edid_->manufacturer_id2 & 0xe0) >> 5) + 'A' - 1);
    uint8_t c3  = static_cast<uint8_t>(((base_edid_->manufacturer_id2 & 0x1f)) + 'A' - 1);

    manufacturer_id_[0] = c1;
    manufacturer_id_[1] = c2;
    manufacturer_id_[2] = c3;
    manufacturer_id_[3] = '\0';
    manufacturer_name_ = lookup_eisa_vid(EISA_ID(c1, c2, c3));

    return true;
}

template<typename T> const T* Edid::GetBlock(uint8_t block_num) const {
    const uint8_t* bytes = bytes_ + block_num * kBlockSize;
    return bytes[0] == T::kTag ? reinterpret_cast<const T*>(bytes) : nullptr;
}

bool Edid::is_hdmi() const {
    data_block_iterator dbs(this);
    if (!dbs.is_valid() || dbs.cea_revision() < 0x03) {
        return false;
    }

    do {
        if (dbs->type() == VendorSpecificBlock::kType) {
            // HDMI's 24-bit IEEE registration is 0x000c03 - vendor_number is little endian
            if (dbs->payload.vendor.vendor_number[0] == 0x03
                    && dbs->payload.vendor.vendor_number[1] == 0x0c
                    && dbs->payload.vendor.vendor_number[2] == 0x00) {
                return true;
            }
        }
    } while ((++dbs).is_valid());
    return false;
}

void convert_dtd_to_timing(const DetailedTimingDescriptor& dtd, timing_params* params) {
    params->pixel_freq_10khz = dtd.pixel_clock_10khz;
    params->horizontal_addressable = dtd.horizontal_addressable();
    params->horizontal_front_porch = dtd.horizontal_front_porch();
    params->horizontal_sync_pulse = dtd.horizontal_sync_pulse_width();
    params->horizontal_blanking = dtd.horizontal_blanking();

    params->vertical_addressable = dtd.vertical_addressable();
    params->vertical_front_porch = dtd.vertical_front_porch();
    params->vertical_sync_pulse = dtd.vertical_sync_pulse_width();
    params->vertical_blanking = dtd.vertical_blanking();

    if (dtd.type() != TYPE_DIGITAL_SEPARATE) {
        printf("edid: Ignoring bad timing type %d\n", dtd.type());
    }
    params->flags = (dtd.vsync_polarity() ? timing_params::kPositiveVsync : 0)
            | (dtd.hsync_polarity() ? timing_params::kPositiveHsync : 0)
            | (dtd.interlaced() ? timing_params::kInterlaced : 0);

    double total_pxls =
            (params->horizontal_addressable + params->horizontal_blanking) *
            (params->vertical_addressable + params->vertical_blanking);
    double pixel_clock_hz = params->pixel_freq_10khz * 1000 * 10;
    params->vertical_refresh_e2 =
            static_cast<uint32_t>(round(100 * pixel_clock_hz / total_pxls));
}

void convert_std_to_timing(const BaseEdid& edid,
                           const StandardTimingDescriptor& std, timing_params* params) {
    // Pick the largest resolution advertised by the display and then use the
    // generalized timing formula to compute the timing parameters.
    // TODO(ZX-1413): Handle secondary GTF and CVT
    // TODO(stevensd): Support interlaced modes and margins
    uint32_t width = std.horizontal_resolution();
    uint32_t height = std.vertical_resolution(edid.edid_version, edid.edid_revision);
    uint32_t v_rate = std.vertical_freq() + 60;

    if (!width || !height || !v_rate) {
        return;
    }

    const timing_params_t* dmt_timing = internal::dmt_timings;
    for (unsigned i = 0; i < internal::dmt_timings_count; i++, dmt_timing++) {
        if (dmt_timing->horizontal_addressable == width
                && dmt_timing->vertical_addressable == height
                && ((dmt_timing->vertical_refresh_e2 + 50) / 100) == v_rate) {
            *params = *dmt_timing;
            return;
        }
    }

    // Default values for GFT variables
    static constexpr uint32_t kCellGran = 8;
    static constexpr uint32_t kMinPorch = 1;
    static constexpr uint32_t kVsyncRequired = 3;
    static constexpr uint32_t kHsyncPercent = 8;
    static constexpr uint32_t kMinVsyncPlusBpUs = 550;
    static constexpr uint32_t kM = 600;
    static constexpr uint32_t kC = 40;
    static constexpr uint32_t kK = 128;
    static constexpr uint32_t kJ = 20;
    static constexpr uint32_t kCPrime = ((kC - kJ) * kK / 256) + kJ;
    static constexpr uint32_t kMPrime = (kK * kM) / 256;

    uint32_t h_pixels_rnd = round_div(width, kCellGran) * kCellGran;
    double h_period_est =
            (1000000.0 - kMinVsyncPlusBpUs * v_rate) / (v_rate * (height + kMinPorch));
    uint32_t vsync_bp = round_div(kMinVsyncPlusBpUs, h_period_est);
    uint32_t v_total_lines = height + vsync_bp + kMinPorch;
    double v_field_rate_est = 1000000.0 / (h_period_est * v_total_lines);
    double h_period = (1.0 * h_period_est * v_field_rate_est) / v_rate;
    double v_field_rate = 1000000.0 / h_period / v_total_lines;
    double ideal_duty_cycle = kCPrime - (kMPrime * h_period_est / 1000);
    uint32_t h_blank_pixels = 2 * kCellGran * round_div(
            h_pixels_rnd * ideal_duty_cycle, (100 - ideal_duty_cycle) * (2 * kCellGran));
    uint32_t total_pixels = h_pixels_rnd + h_blank_pixels;
    double pixel_freq = total_pixels / h_period;

    params->pixel_freq_10khz = (uint32_t) (pixel_freq * 100 + 50);
    params->horizontal_addressable = h_pixels_rnd;
    params->horizontal_sync_pulse =
            round_div(kHsyncPercent * total_pixels, 100 * kCellGran) * kCellGran;
    params->horizontal_front_porch = h_blank_pixels / 2 - params->horizontal_sync_pulse;
    params->horizontal_blanking = h_blank_pixels;
    params->vertical_addressable = height;
    params->vertical_front_porch = kMinPorch;
    params->vertical_sync_pulse = kVsyncRequired;
    params->vertical_blanking = vsync_bp + kMinPorch;

    // TODO(ZX-1413): Set these depending on if we use default/secondary GTF
    params->flags = timing_params::kPositiveVsync;

    params->vertical_refresh_e2 = static_cast<uint32_t>(v_field_rate * 100 + .5);
}

timing_iterator& timing_iterator::operator++() {
    while (state_ != kDone) {
        Advance();
        // If either of these are 0, then the timing value is definitely wrong
        if (params_.vertical_addressable != 0 && params_.horizontal_addressable != 0) {
            break;
        }
    }
    return *this;
}

void timing_iterator::Advance() {
    if (state_ == kDtds) {
        while (descriptors_.is_valid()) {
            if (descriptors_->timing.pixel_clock_10khz != 0) {
                convert_dtd_to_timing(descriptors_->timing, &params_);
                ++descriptors_;
                return;
            }
            ++descriptors_;
        }
        state_ = kSvds;
        state_index_ = UINT16_MAX;
    }

    if (state_ == kSvds) {
        while (dbs_.is_valid()) {
            if (dbs_->type() == ShortVideoDescriptor::kType) {
                state_index_++;
                uint32_t modes_to_skip = state_index_;
                for (unsigned i = 0; i < dbs_->length(); i++) {
                    uint32_t idx = dbs_->payload.video[i].standard_mode_idx() - 1;
                    if (idx >= internal::cea_timings_count) {
                        continue;
                    }
                    if (modes_to_skip == 0) {
                        params_ = internal::cea_timings[idx];
                        return;
                    }

                    // For timings with refresh rates that are multiples of 6, there are
                    // corresponding timings adjusted by a factor of 1000/1001.
                    uint32_t rounded_refresh =
                            (internal::cea_timings[idx].vertical_refresh_e2 + 99) / 100;
                    if (rounded_refresh % 6 == 0) {
                        if (modes_to_skip == 1) {
                            params_ = internal::cea_timings[idx];
                            double clock = params_.pixel_freq_10khz;
                            double refresh = params_.vertical_refresh_e2;
                            // 240/480 height entries are already multipled by 1000/1001
                            double mult = params_.vertical_addressable == 240
                                    || params_.vertical_addressable == 480
                                    ? 1.001 : (1000. / 1001.);
                            params_.pixel_freq_10khz = static_cast<uint32_t>(round(clock * mult));
                            params_.vertical_refresh_e2 =
                                    static_cast<uint32_t>(round(refresh * mult));
                            return;
                        }
                        modes_to_skip -= 2;
                    } else {
                        modes_to_skip--;
                    }
                }
            }

            ++dbs_;
            // Reset the index for either the next SVD block or the STDs.
            state_index_ = UINT16_MAX;
        }

        state_ = kStds;
    }

    if (state_ == kStds) {
        while (++state_index_ < fbl::count_of(edid_->base_edid_->standard_timings)) {
            const StandardTimingDescriptor* desc =
                    edid_->base_edid_->standard_timings + state_index_;
            if (desc->byte1 == 0x01 && desc->byte2 == 0x01) {
                continue;
            }
            convert_std_to_timing(*edid_->base_edid_, *desc, &params_);
            return;
        }

        state_ = kDone;
    }
}

audio_data_block_iterator& audio_data_block_iterator::operator++() {
    while (dbs_.is_valid()) {
        uint32_t num_sads = static_cast<uint32_t>(dbs_->length() / sizeof(ShortAudioDescriptor));
        if (dbs_->type() != ShortAudioDescriptor::kType || ++sad_idx_ > num_sads) {
            ++dbs_;
            sad_idx_ = UINT8_MAX;
            continue;
        }
        descriptor_ = dbs_->payload.audio[sad_idx_];
        return *this;
    }

    edid_ = nullptr;
    return *this;
}

Edid::descriptor_iterator& Edid::descriptor_iterator::operator++() {
    if (!edid_) {
        return *this;
    }

    if (block_idx_ == 0) {
        descriptor_idx_++;

        if (descriptor_idx_ < fbl::count_of(edid_->base_edid_->detailed_descriptors)) {
            descriptor_ = edid_->base_edid_->detailed_descriptors + descriptor_idx_;
            if (descriptor_->timing.pixel_clock_10khz != 0 || descriptor_->monitor.type != 0x10) {
                return *this;
            }
        }

        block_idx_++;
        descriptor_idx_ = UINT32_MAX;
    }

    while (block_idx_ < (edid_->len_ / kBlockSize)) {
        auto cea_extn_block = edid_->GetBlock<CeaEdidTimingExtension>(block_idx_);
        size_t offset = sizeof(CeaEdidTimingExtension::payload);
        if (cea_extn_block &&
                cea_extn_block->dtd_start_idx > offsetof(CeaEdidTimingExtension, payload)) {
            offset = cea_extn_block->dtd_start_idx - offsetof(CeaEdidTimingExtension, payload);
        }

        descriptor_idx_++;
        offset += sizeof(Descriptor) * descriptor_idx_;

        // Return if the descriptor is within bounds and either a timing descriptor or not
        // a dummy monitor descriptor, otherwise advance to the next block
        if (offset + sizeof(DetailedTimingDescriptor) <= sizeof(CeaEdidTimingExtension::payload)) {
            descriptor_ = reinterpret_cast<const Descriptor*>(cea_extn_block->payload + offset);
            if (descriptor_->timing.pixel_clock_10khz != 0
                    || descriptor_->monitor.type != Descriptor::Monitor::kDummyType) {
                return *this;
            }
        }

        block_idx_++;
        descriptor_idx_ = UINT32_MAX;
    }

    edid_ = nullptr;
    return *this;
}

Edid::data_block_iterator::data_block_iterator(const Edid* edid) : edid_(edid) {
    ++(*this);
    if (is_valid()) {
        cea_revision_ = edid_->GetBlock<CeaEdidTimingExtension>(block_idx_)->revision_number;
    }
}

Edid::data_block_iterator& Edid::data_block_iterator::operator++() {
    if (!edid_) {
        return *this;
    }

    while (block_idx_ < (edid_->len_ / kBlockSize)) {
        auto cea_extn_block = edid_->GetBlock<CeaEdidTimingExtension>(block_idx_);
        size_t dbc_end = 0;
        if (cea_extn_block &&
                cea_extn_block->dtd_start_idx > offsetof(CeaEdidTimingExtension, payload)) {
            dbc_end = cea_extn_block->dtd_start_idx - offsetof(CeaEdidTimingExtension, payload);
        }

        db_idx_++;
        uint32_t db_to_skip = db_idx_;

        uint32_t offset = 0;
        while (offset < dbc_end) {
            auto* dblk = reinterpret_cast<const DataBlock*>(cea_extn_block->payload + offset);
            if (db_to_skip == 0) {
                db_ = dblk;
                return *this;
            }
            db_to_skip--;
            offset += (dblk->length() + 1); // length doesn't include the data block header byte
        }

        block_idx_++;
        db_idx_ = UINT32_MAX;
    }

    edid_ = nullptr;
    return *this;
}

void Edid::Print(void (*print_fn)(const char* str)) const {
    char str_buf[128];
    print_fn("Raw edid:\n");
    for (auto i = 0; i < edid_length(); i++) {
        constexpr int kBytesPerLine = 16;
        char *b = str_buf;
        if (i % kBytesPerLine == 0) {
            b += sprintf(b, "%04x: ", i);
        }
        sprintf(b, "%02x%s", edid_bytes()[i],
                i % kBytesPerLine == kBytesPerLine - 1 ? "\n" : " ");
        print_fn(str_buf);
    }
}

bool Edid::supports_basic_audio() const {
    uint8_t block_idx = 1; // Skip block 1, since it can't be a CEA block
    while (block_idx < (len_ / kBlockSize)) {
        auto cea_extn_block = GetBlock<CeaEdidTimingExtension>(block_idx);
        if (cea_extn_block && cea_extn_block->revision_number >= 2) {
            return cea_extn_block->basic_audio();
        }
        block_idx++;
    }
    return false;
}

} // namespace edid
