/*
 * 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 <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(int width, int height, int row_bytes, int pixel_bytes,
                                             size_t data_size) {
  static constexpr size_t kSurfaceDataAlignment = 8;
  // Cannot use std::make_unique to access non-public ctor.
  auto result = std::unique_ptr<GRSurface>(new GRSurface(width, height, row_bytes, pixel_bytes));
  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, data_size_);
  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, width * height * 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 height_per_frame = height / *frames;
    auto created_surface =
        GRSurface::Create(width, height_per_frame, width * 4, 4, width * height_per_frame * 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, width * height);
  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, w * h);
      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);
}
