/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "private/resources.h"

#include <fcntl.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>

#include <limits>
#include <memory>
#include <regex>
#include <string>
#include <vector>

#include <android-base/strings.h>
#include <png.h>

#include "minui/minui.h"

static std::string g_resource_dir{ "/res/images" };

std::unique_ptr<GRSurface> GRSurface::Create(size_t width, size_t height, size_t row_bytes,
                                             size_t pixel_bytes) {
  if (width == 0 || row_bytes == 0 || height == 0 || pixel_bytes == 0) return nullptr;
  if (std::numeric_limits<size_t>::max() / row_bytes < height) return nullptr;

  // Cannot use std::make_unique to access non-public ctor.
  auto result = std::unique_ptr<GRSurface>(new GRSurface(width, height, row_bytes, pixel_bytes));
  size_t data_size = row_bytes * height;
  result->data_size_ =
      (data_size + kSurfaceDataAlignment - 1) / kSurfaceDataAlignment * kSurfaceDataAlignment;
  result->data_.reset(
      static_cast<uint8_t*>(aligned_alloc(kSurfaceDataAlignment, result->data_size_)));
  if (!result->data_) return nullptr;
  return result;
}

std::unique_ptr<GRSurface> GRSurface::Clone() const {
  auto result = GRSurface::Create(width, height, row_bytes, pixel_bytes);
  if (!result) return nullptr;
  memcpy(result->data(), data(), data_size_);
  return result;
}

PngHandler::PngHandler(const std::string& name) {
  std::string res_path = g_resource_dir + "/" + name + ".png";
  png_fp_.reset(fopen(res_path.c_str(), "rbe"));
  // Try to read from |name| if the resource path does not work.
  if (!png_fp_) {
    png_fp_.reset(fopen(name.c_str(), "rbe"));
  }
  if (!png_fp_) {
    error_code_ = -1;
    return;
  }

  uint8_t header[8];
  size_t bytesRead = fread(header, 1, sizeof(header), png_fp_.get());
  if (bytesRead != sizeof(header)) {
    error_code_ = -2;
    return;
  }

  if (png_sig_cmp(header, 0, sizeof(header))) {
    error_code_ = -3;
    return;
  }

  png_ptr_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!png_ptr_) {
    error_code_ = -4;
    return;
  }

  info_ptr_ = png_create_info_struct(png_ptr_);
  if (!info_ptr_) {
    error_code_ = -5;
    return;
  }

  if (setjmp(png_jmpbuf(png_ptr_))) {
    error_code_ = -6;
    return;
  }

  png_init_io(png_ptr_, png_fp_.get());
  png_set_sig_bytes(png_ptr_, sizeof(header));
  png_read_info(png_ptr_, info_ptr_);

  png_get_IHDR(png_ptr_, info_ptr_, &width_, &height_, &bit_depth_, &color_type_, nullptr, nullptr,
               nullptr);

  channels_ = png_get_channels(png_ptr_, info_ptr_);

  if (bit_depth_ == 8 && channels_ == 3 && color_type_ == PNG_COLOR_TYPE_RGB) {
    // 8-bit RGB images: great, nothing to do.
  } else if (bit_depth_ <= 8 && channels_ == 1 && color_type_ == PNG_COLOR_TYPE_GRAY) {
    // 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray.
    png_set_expand_gray_1_2_4_to_8(png_ptr_);
  } else if (bit_depth_ <= 8 && channels_ == 1 && color_type_ == PNG_COLOR_TYPE_PALETTE) {
    // paletted images: expand to 8-bit RGB.  Note that we DON'T
    // currently expand the tRNS chunk (if any) to an alpha
    // channel, because minui doesn't support alpha channels in
    // general.
    png_set_palette_to_rgb(png_ptr_);
    channels_ = 3;
  } else {
    fprintf(stderr, "minui doesn't support PNG depth %d channels %d color_type %d\n", bit_depth_,
            channels_, color_type_);
    error_code_ = -7;
  }
}

PngHandler::~PngHandler() {
  if (png_ptr_) {
    png_destroy_read_struct(&png_ptr_, &info_ptr_, nullptr);
  }
}

// "display" surfaces are transformed into the framebuffer's required pixel format (currently only
// RGBX is supported) at load time, so gr_blit() can be nothing more than a memcpy() for each row.

// Copies 'input_row' to 'output_row', transforming it to the framebuffer pixel format. The input
// format depends on the value of 'channels':
//
//   1 - input is 8-bit grayscale
//   3 - input is 24-bit RGB
//   4 - input is 32-bit RGBA/RGBX
//
// 'width' is the number of pixels in the row.
static void TransformRgbToDraw(const uint8_t* input_row, uint8_t* output_row, int channels,
                               int width) {
  const uint8_t* ip = input_row;
  uint8_t* op = output_row;

  switch (channels) {
    case 1:
      // expand gray level to RGBX
      for (int x = 0; x < width; ++x) {
        *op++ = *ip;
        *op++ = *ip;
        *op++ = *ip;
        *op++ = 0xff;
        ip++;
      }
      break;

    case 3:
      // expand RGBA to RGBX
      for (int x = 0; x < width; ++x) {
        *op++ = *ip++;
        *op++ = *ip++;
        *op++ = *ip++;
        *op++ = 0xff;
      }
      break;

    case 4:
      // copy RGBA to RGBX
      memcpy(output_row, input_row, width * 4);
      break;
  }
}

int res_create_display_surface(const char* name, GRSurface** pSurface) {
  *pSurface = nullptr;

  PngHandler png_handler(name);
  if (!png_handler) return png_handler.error_code();

  png_structp png_ptr = png_handler.png_ptr();
  png_uint_32 width = png_handler.width();
  png_uint_32 height = png_handler.height();

  auto surface = GRSurface::Create(width, height, width * 4, 4);
  if (!surface) {
    return -8;
  }

  PixelFormat pixel_format = gr_pixel_format();
  if (pixel_format == PixelFormat::ABGR || pixel_format == PixelFormat::BGRA) {
    png_set_bgr(png_ptr);
  }

  for (png_uint_32 y = 0; y < height; ++y) {
    std::vector<uint8_t> p_row(width * 4);
    png_read_row(png_ptr, p_row.data(), nullptr);
    TransformRgbToDraw(p_row.data(), surface->data() + y * surface->row_bytes,
                       png_handler.channels(), width);
  }

  *pSurface = surface.release();

  return 0;
}

int res_create_multi_display_surface(const char* name, int* frames, int* fps,
                                     GRSurface*** pSurface) {
  *pSurface = nullptr;
  *frames = -1;

  PngHandler png_handler(name);
  if (!png_handler) return png_handler.error_code();

  png_structp png_ptr = png_handler.png_ptr();
  png_uint_32 width = png_handler.width();
  png_uint_32 height = png_handler.height();

  *frames = 1;
  *fps = 20;
  png_textp text;
  int num_text;
  if (png_get_text(png_ptr, png_handler.info_ptr(), &text, &num_text)) {
    for (int i = 0; i < num_text; ++i) {
      if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) {
        *frames = atoi(text[i].text);
      } else if (text[i].key && strcmp(text[i].key, "FPS") == 0 && text[i].text) {
        *fps = atoi(text[i].text);
      }
    }
    printf("  found frames = %d\n", *frames);
    printf("  found fps = %d\n", *fps);
  }

  int result = 0;
  GRSurface** surface = nullptr;
  if (*frames <= 0 || *fps <= 0) {
    printf("bad number of frames (%d) and/or FPS (%d)\n", *frames, *fps);
    result = -10;
    goto exit;
  }

  if (height % *frames != 0) {
    printf("bad height (%d) for frame count (%d)\n", height, *frames);
    result = -9;
    goto exit;
  }

  surface = static_cast<GRSurface**>(calloc(*frames, sizeof(GRSurface*)));
  if (!surface) {
    result = -8;
    goto exit;
  }
  for (int i = 0; i < *frames; ++i) {
    auto created_surface = GRSurface::Create(width, height / *frames, width * 4, 4);
    if (!created_surface) {
      result = -8;
      goto exit;
    }
    surface[i] = created_surface.release();
  }

  if (gr_pixel_format() == PixelFormat::ABGR || gr_pixel_format() == PixelFormat::BGRA) {
    png_set_bgr(png_ptr);
  }

  for (png_uint_32 y = 0; y < height; ++y) {
    std::vector<uint8_t> p_row(width * 4);
    png_read_row(png_ptr, p_row.data(), nullptr);
    int frame = y % *frames;
    uint8_t* out_row = surface[frame]->data() + (y / *frames) * surface[frame]->row_bytes;
    TransformRgbToDraw(p_row.data(), out_row, png_handler.channels(), width);
  }

  *pSurface = surface;

exit:
  if (result < 0) {
    if (surface) {
      for (int i = 0; i < *frames; ++i) {
        free(surface[i]);
      }
      free(surface);
    }
  }
  return result;
}

int res_create_alpha_surface(const char* name, GRSurface** pSurface) {
  *pSurface = nullptr;

  PngHandler png_handler(name);
  if (!png_handler) return png_handler.error_code();

  if (png_handler.channels() != 1) {
    return -7;
  }

  png_structp png_ptr = png_handler.png_ptr();
  png_uint_32 width = png_handler.width();
  png_uint_32 height = png_handler.height();

  auto surface = GRSurface::Create(width, height, width, 1);
  if (!surface) {
    return -8;
  }

  PixelFormat pixel_format = gr_pixel_format();
  if (pixel_format == PixelFormat::ABGR || pixel_format == PixelFormat::BGRA) {
    png_set_bgr(png_ptr);
  }

  for (png_uint_32 y = 0; y < height; ++y) {
    uint8_t* p_row = surface->data() + y * surface->row_bytes;
    png_read_row(png_ptr, p_row, nullptr);
  }

  *pSurface = surface.release();

  return 0;
}

void res_set_resource_dir(const std::string& dirname) {
  g_resource_dir = dirname;
}

// This function tests if a locale string stored in PNG (prefix) matches
// the locale string provided by the system (locale).
bool matches_locale(const std::string& prefix, const std::string& locale) {
  // According to the BCP 47 format, A locale string may consists of:
  // language-{extlang}-{script}-{region}-{variant}
  // The locale headers in PNG mostly consist of language-{region} except for sr-Latn, and some
  // android's system locale can have the format language-{script}-{region}.

  // Return true if the whole string of prefix matches the top part of locale. Otherwise try to
  // match the locale string without the {script} section.
  // For instance, prefix == "en" matches locale == "en-US", prefix == "sr-Latn" matches locale
  // == "sr-Latn-BA", and prefix == "zh-CN" matches locale == "zh-Hans-CN".
  if (android::base::StartsWith(locale, prefix)) {
    return true;
  }

  size_t separator = prefix.find('-');
  if (separator == std::string::npos) {
    return false;
  }
  std::regex loc_regex(prefix.substr(0, separator) + "-[A-Za-z]*" + prefix.substr(separator));
  return std::regex_match(locale, loc_regex);
}

std::vector<std::string> get_locales_in_png(const std::string& png_name) {
  PngHandler png_handler(png_name);
  if (!png_handler) {
    printf("Failed to open %s, error: %d\n", png_name.c_str(), png_handler.error_code());
    return {};
  }
  if (png_handler.channels() != 1) {
    printf("Expect input png to have 1 data channel, this file has %d\n", png_handler.channels());
    return {};
  }

  std::vector<std::string> result;
  std::vector<uint8_t> row(png_handler.width());
  for (png_uint_32 y = 0; y < png_handler.height(); ++y) {
    png_read_row(png_handler.png_ptr(), row.data(), nullptr);
    int h = (row[3] << 8) | row[2];
    std::string loc(reinterpret_cast<char*>(&row[5]));
    if (!loc.empty()) {
      result.push_back(loc);
    }
    for (int i = 0; i < h; ++i, ++y) {
      png_read_row(png_handler.png_ptr(), row.data(), nullptr);
    }
  }

  return result;
}

int res_create_localized_alpha_surface(const char* name,
                                       const char* locale,
                                       GRSurface** pSurface) {
  *pSurface = nullptr;
  if (locale == nullptr) {
    return 0;
  }

  PngHandler png_handler(name);
  if (!png_handler) return png_handler.error_code();

  if (png_handler.channels() != 1) {
    return -7;
  }

  png_structp png_ptr = png_handler.png_ptr();
  png_uint_32 width = png_handler.width();
  png_uint_32 height = png_handler.height();

  for (png_uint_32 y = 0; y < height; ++y) {
    std::vector<uint8_t> row(width);
    png_read_row(png_ptr, row.data(), nullptr);
    int w = (row[1] << 8) | row[0];
    int h = (row[3] << 8) | row[2];
    __unused int len = row[4];
    char* loc = reinterpret_cast<char*>(&row[5]);

    if (y + 1 + h >= height || matches_locale(loc, locale)) {
      printf("  %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y);

      auto surface = GRSurface::Create(w, h, w, 1);
      if (!surface) {
        return -8;
      }

      for (int i = 0; i < h; ++i, ++y) {
        png_read_row(png_ptr, row.data(), nullptr);
        memcpy(surface->data() + i * w, row.data(), w);
      }

      *pSurface = surface.release();
      break;
    }

    for (int i = 0; i < h; ++i, ++y) {
      png_read_row(png_ptr, row.data(), nullptr);
    }
  }

  return 0;
}

void res_free_surface(GRSurface* surface) {
  free(surface);
}
