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

#include <fbl/algorithm.h>
#include <fbl/alloc_checker.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_ = std::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
