// Copyright 2013 The Flutter 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 "impeller/renderer/backend/gles/description_gles.h"

#include <algorithm>
#include <cctype>
#include <iomanip>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "impeller/base/strings.h"
#include "impeller/base/validation.h"
#include "impeller/renderer/backend/gles/proc_table_gles.h"

namespace impeller {

static std::string GetGLString(const ProcTableGLES& gl, GLenum name) {
  auto str = gl.GetString(name);
  if (str == nullptr) {
    return "";
  }
  return reinterpret_cast<const char*>(str);
}

static bool DetermineIfES(const std::string& version) {
  return HasPrefix(version, "OpenGL ES");
}

static std::optional<Version> DetermineVersion(std::string version) {
  // Format for OpenGL "OpenGL<space>ES<space><version
  // number><space><vendor-specific information>".
  //
  // Format for OpenGL SL "OpenGL<space>ES<space>GLSL<space>ES<space><version
  // number><space><vendor-specific information>"
  //
  // The prefixes appear to be absent on Desktop GL.

  version = StripPrefix(version, "OpenGL ES ");
  version = StripPrefix(version, "GLSL ES ");

  if (version.empty()) {
    return std::nullopt;
  }

  std::stringstream stream;
  for (size_t i = 0; i < version.size(); i++) {
    const auto character = version[i];
    if (std::isdigit(character) || character == '.') {
      stream << character;
    } else {
      break;
    }
  }
  std::istringstream istream;
  istream.str(stream.str());
  std::vector<size_t> version_components;
  for (std::string version_component;
       std::getline(istream, version_component, '.');) {
    version_components.push_back(std::stoul(version_component));
  }
  return Version::FromVector(std::move(version_components));
}

DescriptionGLES::DescriptionGLES(const ProcTableGLES& gl)
    : vendor_(GetGLString(gl, GL_VENDOR)),
      renderer_(GetGLString(gl, GL_RENDERER)),
      gl_version_string_(GetGLString(gl, GL_VERSION)),
      sl_version_string_(GetGLString(gl, GL_SHADING_LANGUAGE_VERSION)) {
  const auto extensions = GetGLString(gl, GL_EXTENSIONS);
  std::stringstream extensions_stream(extensions);
  std::string extension;
  while (std::getline(extensions_stream, extension, ' ')) {
    extensions_.insert(extension);
  }

  is_es_ = DetermineIfES(gl_version_string_);

  auto gl_version = DetermineVersion(gl_version_string_);
  if (!gl_version.has_value()) {
    VALIDATION_LOG << "Could not determine GL version.";
    return;
  }
  gl_version_ = gl_version.value();

  auto sl_version = DetermineVersion(sl_version_string_);
  if (!sl_version.has_value()) {
    VALIDATION_LOG << "Could not determine SL version.";
    return;
  }
  sl_version_ = sl_version.value();

  is_valid_ = true;
}

DescriptionGLES::~DescriptionGLES() = default;

bool DescriptionGLES::IsValid() const {
  return is_valid_;
}

std::string DescriptionGLES::GetString() const {
  if (!IsValid()) {
    return "Unknown Renderer.";
  }

  std::vector<std::pair<std::string, std::string>> items;

  items.emplace_back(std::make_pair("Vendor", vendor_));
  items.emplace_back(std::make_pair("Renderer", renderer_));
  items.emplace_back(std::make_pair("GL Version", gl_version_string_));
  items.emplace_back(
      std::make_pair("Shading Language Version", sl_version_string_));
  items.emplace_back(
      std::make_pair("Extensions", std::to_string(extensions_.size())));

  size_t max_width = 0u;
  for (const auto& item : items) {
    max_width = std::max(max_width, item.first.size());
  }

  std::stringstream stream;
  stream << "OpenGL Renderer:" << std::endl;
  for (const auto& item : items) {
    stream << std::setw(max_width + 1) << item.first << ": " << item.second
           << std::endl;
  }

  const auto pad = std::string(max_width + 3, ' ');
  for (const auto& extension : extensions_) {
    stream << pad << extension << std::endl;
  }

  return stream.str();
}

bool DescriptionGLES::IsES() const {
  return is_es_;
}

bool DescriptionGLES::HasExtension(const std::string& ext) const {
  return extensions_.find(ext) != extensions_.end();
}

bool DescriptionGLES::HasDebugExtension() const {
  return HasExtension("GL_KHR_debug");
}

}  // namespace impeller
