// Copyright (c) 2010 The Chromium OS 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 <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#include "base/logging.h"

#include "glinterface.h"
#include "main.h"
#include "utils.h"

using base::FilePath;

const char* kGlesHeader =
    "#ifdef GL_ES\n"
    "precision highp float;\n"
    "#endif\n";

FilePath *g_base_path = new FilePath();
double g_initial_temperature = -1000.0;

// Sets the base path for MmapFile to `dirname($argv0)`/$relative.
void SetBasePathFromArgv0(const char* argv0, const char* relative) {
  if (g_base_path) {
    delete g_base_path;
  }
  FilePath argv0_path = FilePath(argv0).DirName();
  FilePath base_path = relative ? argv0_path.Append(relative) : argv0_path;
  g_base_path = new FilePath(base_path);
}

const FilePath& GetBasePath() {
  return *g_base_path;
}

void *MmapFile(const char* name, size_t* length) {
  FilePath filename = g_base_path->Append(name);
  int fd = open(filename.value().c_str(), O_RDONLY);
  if (fd == -1)
    return NULL;

  struct stat sb;
  CHECK(fstat(fd, &sb) != -1);

  char *mmap_ptr = static_cast<char *>(
    mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0));

  close(fd);

  if (mmap_ptr)
    *length = sb.st_size;

  return mmap_ptr;
}

bool read_int_from_file(FilePath filename, int *value) {
  FILE *fd = fopen(filename.value().c_str(), "r");
  if (!fd) {
    return false;
  }
  int count = fscanf(fd, "%d", value);
  if (count != 1) {
    printf("Error: could not read integer from file. (%s)\n",
           filename.value().c_str());
    if(count != 1)
      return false;
  }
  fclose(fd);
  return true;
}

// Returns temperature at which CPU gets throttled.
// TODO(ihf): update this based on the outcome of crbug.com/356422.
double get_temperature_critical() {
  FilePath filename = FilePath("/sys/class/hwmon/hwmon0/temp1_crit");
  int temperature_mCelsius = 0;
  if (!read_int_from_file(filename, &temperature_mCelsius)) {
    // spring is special :-(.
    filename = FilePath("/sys/devices/virtual/hwmon/hwmon1/temp1_crit");
    if (!read_int_from_file(filename, &temperature_mCelsius)) {
      // 85'C is the minimum observed critical temperature so far.
      printf("Warning: guessing critical temperature as 85'C.\n");
      return 85.0;
    }
  }
  double temperature_Celsius = 0.001 * temperature_mCelsius;
  // Simple sanity check for reasonable critical temperatures.
  assert(temperature_Celsius >= 60.0);
  assert(temperature_Celsius <= 150.0);
  return temperature_Celsius;
}


// Returns currently measured temperature.
// TODO(ihf): update this based on the outcome of crbug.com/356422.
double get_temperature_input() {
  FilePath filenames[] = {
      FilePath("/sys/class/hwmon/hwmon0/temp1_input"),
      FilePath("/sys/class/hwmon/hwmon1/temp1_input"),
      FilePath("/sys/devices/platform/coretemp.0/temp1_input"),
      FilePath("/sys/devices/platform/coretemp.0/temp2_input"),
      FilePath("/sys/devices/platform/coretemp.0/temp3_input"),
      FilePath("/sys/devices/virtual/hwmon/hwmon0/temp1_input"),
      FilePath("/sys/devices/virtual/hwmon/hwmon0/temp2_input"),
      FilePath("/sys/devices/virtual/hwmon/hwmon1/temp1_input"),
      FilePath("/sys/devices/virtual/hwmon/hwmon2/temp1_input"),
      FilePath("/sys/devices/virtual/hwmon/hwmon3/temp1_input"),
      FilePath("/sys/devices/virtual/hwmon/hwmon4/temp1_input"),
  };

  int temperature_mCelsius = 0;
  int max_temperature_mCelsius = -1000000.0;
  for (unsigned int i = 0; i < sizeof(filenames) / sizeof(FilePath); i++) {
    if (read_int_from_file(filenames[i], &temperature_mCelsius)) {
      // Hack: Ignore values outside of 10'C...150'C for now.
      if (temperature_mCelsius < 10000 || temperature_mCelsius > 150000) {
        printf("Warning: ignoring temperature reading of %d m'C.\n",
               temperature_mCelsius);
      } else {
        max_temperature_mCelsius = std::max(max_temperature_mCelsius,
                                            temperature_mCelsius);
      }
    }
  }

  double temperature_Celsius = 0.001 * max_temperature_mCelsius;
  if (temperature_Celsius < 10.0 || temperature_Celsius > 150.0) {
    printf("Warning: ignoring temperature reading of %f'C.\n",
           temperature_Celsius);
  }

  return temperature_Celsius;
}

const double GetInitialMachineTemperature() {
  return g_initial_temperature;
}

// TODO(ihf): update this based on the outcome of crbug.com/356422.
// In particular we should probably just have a system script that we can call
// and read the output from.
double GetMachineTemperature() {
  double max_temperature = get_temperature_input();
  return max_temperature;
}

// Waits up to timeout seconds to reach cold_temperature in Celsius.
double WaitForCoolMachine(double cold_temperature, double timeout,
                          double *temperature) {
  // Integer times are in micro-seconds.
  uint64_t time_start = GetUTime();
  uint64_t time_now = time_start;
  uint64_t time_end = time_now + 1e6 * timeout;
  *temperature = GetMachineTemperature();
  while (time_now < time_end) {
    if (*temperature < cold_temperature)
      break;
    sleep(1.0);
    time_now = GetUTime();
    *temperature = GetMachineTemperature();
  }
  double wait_time = 1.0e-6 * (time_now - time_start);
  assert(wait_time >= 0);
  assert(wait_time < timeout + 5.0);
  return wait_time;
}

namespace glbench {

GLuint SetupTexture(GLsizei size_log2) {
  GLsizei size = 1 << size_log2;
  GLuint name = ~0;
  glGenTextures(1, &name);
  glBindTexture(GL_TEXTURE_2D, name);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  unsigned char *pixels = new unsigned char[size * size * 4];
  if (!pixels)
    return 0;

  for (GLint level = 0; size > 0; level++, size /= 2) {
    unsigned char *p = pixels;
    for (int i = 0; i < size; i++) {
      for (int j = 0; j < size; j++) {
        *p++ = level %3 != 0 ? (i ^ j) << level : 0;
        *p++ = level %3 != 1 ? (i ^ j) << level : 0;
        *p++ = level %3 != 2 ? (i ^ j) << level : 0;
        *p++ = 255;
      }
    }
    if (size == 1) {
      unsigned char *p = pixels;
      *p++ = 255;
      *p++ = 255;
      *p++ = 255;
      *p++ = 255;
    }
    glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
  }
  delete[] pixels;
  return name;
}

GLuint SetupVBO(GLenum target, GLsizeiptr size, const GLvoid *data) {
  GLuint buf = ~0;
  glGenBuffers(1, &buf);
  glBindBuffer(target, buf);
  glBufferData(target, size, data, GL_STATIC_DRAW);
  CHECK(!glGetError());
  return buf;
}

// Generates a lattice symmetric around the origin (all quadrants).
void CreateLattice(GLfloat **vertices, GLsizeiptr *size,
                   GLfloat size_x, GLfloat size_y, int width, int height)
{
  GLfloat *vptr = *vertices = new GLfloat[2 * (width + 1) * (height + 1)];
  GLfloat shift_x = size_x * width;
  GLfloat shift_y = size_y * height;
  for (int j = 0; j <= height; j++) {
    for (int i = 0; i <= width; i++) {
      *vptr++ = 2 * i * size_x - shift_x;
      *vptr++ = 2 * j * size_y - shift_y;
    }
  }
  *size = (vptr - *vertices) * sizeof(GLfloat);
}

// Generates a mesh of 2*width*height triangles.  The ratio of front facing to
// back facing triangles is culled_ratio/RAND_MAX.  Returns the number of
// vertices in the mesh.
int CreateMesh(GLushort **indices, GLsizeiptr *size,
               int width, int height, int culled_ratio) {
  srand(0);

  // We use 16 bit indices for compatibility with GL ES
  CHECK(height * width + width + height <= 65535);

  GLushort *iptr = *indices = new GLushort[2 * 3 * (width * height)];
  const int swath_height = 4;

  CHECK(width % swath_height == 0 && height % swath_height == 0);

  for (int j = 0; j < height; j += swath_height) {
    for (int i = 0; i < width; i++) {
      for (int j2 = 0; j2 < swath_height; j2++) {
        GLushort first = (j + j2) * (width + 1) + i;
        GLushort second = first + 1;
        GLushort third = first + (width + 1);
        GLushort fourth = third + 1;

        bool flag = rand() < culled_ratio;
        *iptr++ = first;
        *iptr++ = flag ? second : third;
        *iptr++ = flag ? third : second;

        *iptr++ = fourth;
        *iptr++ = flag ? third : second;
        *iptr++ = flag ? second : third;
      }
    }
  }
  *size = (iptr - *indices) * sizeof(GLushort);

  return iptr - *indices;
}

static void print_info_log(int obj, bool shader)
{
  char info_log[4096];
  int length;

  if (shader)
    glGetShaderInfoLog(obj, sizeof(info_log)-1, &length, info_log);
  else
    glGetProgramInfoLog(obj, sizeof(info_log)-1, &length, info_log);

  char *p = info_log;
  while (p < info_log + length) {
    char *newline = strchr(p, '\n');
    if (newline)
      *newline = '\0';
    printf("# Info: glGet%sInfoLog: %s\n", shader ? "Shader" : "Program", p);
    if (!newline)
      break;
    p = newline + 1;
  }
}

static void print_shader_log(int shader)
{
  print_info_log(shader, true);
}

static void print_program_log(int program)
{
  print_info_log(program, false);
}


GLuint InitShaderProgram(const char *vertex_src, const char *fragment_src) {
  return InitShaderProgramWithHeader(NULL, vertex_src, fragment_src);
}

GLuint InitShaderProgramWithHeader(const char* header,
                                   const char* vertex_src,
                                   const char* fragment_src) {
  const char* headers[] = {kGlesHeader, header};
  return InitShaderProgramWithHeaders(headers,
                                      arraysize(headers) - (header ? 0 : 1),
                                      vertex_src, fragment_src);
}

GLuint InitShaderProgramWithHeaders(const char** headers,
                                    int count,
                                    const char* vertex_src,
                                    const char* fragment_src) {
  GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
  GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);

  const char** header_and_body = new const char*[count + 1];
  if (count != 0)
    memcpy(header_and_body, headers, count * sizeof(const char*));
  header_and_body[count] = vertex_src;
  glShaderSource(vertex_shader, count + 1, header_and_body, NULL);
  header_and_body[count] = fragment_src;
  glShaderSource(fragment_shader, count + 1, header_and_body, NULL);
  delete[] header_and_body;

  glCompileShader(vertex_shader);
  print_shader_log(vertex_shader);
  glCompileShader(fragment_shader);
  print_shader_log(fragment_shader);

  GLuint program = glCreateProgram();
  glAttachShader(program, vertex_shader);
  glAttachShader(program, fragment_shader);
  glLinkProgram(program);
  print_program_log(program);
  glUseProgram(program);

  glDeleteShader(vertex_shader);
  glDeleteShader(fragment_shader);

  return program;
}

void ClearBuffers() {
  glClearColor(1.f, 0, 0, 1.f);
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  g_main_gl_interface->SwapBuffers();
  glClearColor(0, 1.f, 0, 1.f);
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  g_main_gl_interface->SwapBuffers();
  glClearColor(0, 0, 0.f, 0.f);
}

} // namespace glbench
