// 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 <assert.h>
#include <fcntl.h>
#include <gflags/gflags.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

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

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

FilePath* g_runtime_path = new FilePath();
double g_initial_temperature = -1000.0;
std::string autotest_temperature_script =
    "/usr/local/autotest/bin/temperature.py";
DEFINE_string(TEMPERATURE_SCRIPT_PATH,
              autotest_temperature_script,
              "The path to temperature measurement executable.");

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

void* MmapFile(const char* name, size_t* length) {
  FilePath filename = g_runtime_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;
}

void printDateTime() {
  char            fmt[64], time_string[64];
  struct timeval  tv;
  struct tm       *tm;
  gettimeofday(&tv, NULL);
  if((tm = localtime(&tv.tv_sec)) != NULL){
    strftime(fmt, sizeof fmt, "%a %b %e %H:%M:%S.%%06u %Y", tm);
    snprintf(time_string, sizeof time_string, fmt, tv.tv_usec);
    printf("# DateTime: %s\n", time_string);
  }
}

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;
}

bool read_float_from_cmd_output(const char* command, double* value) {
  FILE* fd = popen(command, "r");
  if (!fd) {
    printf("Error: could not popen command. (%s)\n", command);
    return false;
  }
  int count = fscanf(fd, "%lf", value);
  if (count != 1) {
    printf("Error: could not read float from command output. (%s)\n", command);
    return false;
  }
  pclose(fd);
  return true;
}

bool check_file_existence(const char* file_path, struct stat* buffer = NULL) {
  struct stat local_buf;
  bool exist = stat(file_path, &local_buf) == 0;
  if (buffer && exist)
    memcpy(buffer, &local_buf, sizeof(local_buf));
  return exist;
}

bool check_dir_existence(const char* file_path) {
  struct stat buffer;
  bool exist = check_file_existence(file_path, &buffer);
  if (!exist)
    return false;
  return S_ISDIR(buffer.st_mode);
}

// Returns currently measured temperature.
double get_temperature_input() {
  std::string command = FLAGS_TEMPERATURE_SCRIPT_PATH;
  if (command == autotest_temperature_script) {
    command += " --maximum";
  }
  double temperature_Celsius = -1000.0;
  read_float_from_cmd_output(command.c_str(), &temperature_Celsius);
  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;
}

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;
}

std::vector<std::string> SplitString(std::string& input,
                                     std::string delimiter,
                                     bool trim_space) {
  std::vector<std::string> result;
  if (input.empty())
    return result;
  size_t start = 0;
  while (start != std::string::npos) {
    size_t end = input.find(delimiter, start);
    std::string piece;
    if (end == std::string::npos) {
      piece = input.substr(start);
      start = end;
    } else {
      piece = input.substr(start, end - start);
      start = end + 1;
    }
    trim(piece);
    result.push_back(piece);
  }
  return result;
}

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, 1.f);
}

}  // namespace glbench
