/*
 * Copyright (C) 2018 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 <dirent.h>
#include <stdio.h>
#include <stdlib.h>

#include <memory>
#include <string>
#include <vector>

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

#include "minui/minui.h"
#include "private/resources.h"

static const std::string kLocale = "zu";

static const std::vector<std::string> kResourceImagesDirs{
  "res-testdata/res-mdpi/images/",    "res-testdata/res-hdpi/images/",
  "res-testdata/res-xhdpi/images/",   "res-testdata/res-xxhdpi/images/",
  "res-testdata/res-xxxhdpi/images/",
};

static int png_filter(const dirent* de) {
  if (de->d_type != DT_REG || !android::base::EndsWith(de->d_name, "_text.png")) {
    return 0;
  }
  return 1;
}

// Finds out all the PNG files to test, which stay under the same dir with the executabl..
static std::vector<std::string> add_files() {
  std::vector<std::string> files;
  for (const std::string& images_dir : kResourceImagesDirs) {
    static std::string exec_dir = android::base::GetExecutableDirectory();
    std::string dir_path = exec_dir + "/" + images_dir;
    dirent** namelist;
    int n = scandir(dir_path.c_str(), &namelist, png_filter, alphasort);
    if (n == -1) {
      printf("Failed to scandir %s: %s\n", dir_path.c_str(), strerror(errno));
      continue;
    }
    if (n == 0) {
      printf("No file is added for test in %s\n", dir_path.c_str());
    }

    while (n--) {
      std::string file_path = dir_path + namelist[n]->d_name;
      files.push_back(file_path);
      free(namelist[n]);
    }
    free(namelist);
  }
  return files;
}

class ResourcesTest : public testing::TestWithParam<std::string> {
 public:
  static std::vector<std::string> png_list;

 protected:
  void SetUp() override {
    png_ = std::make_unique<PngHandler>(GetParam());
    ASSERT_TRUE(png_);

    ASSERT_EQ(PNG_COLOR_TYPE_GRAY, png_->color_type()) << "Recovery expects grayscale PNG file.";
    ASSERT_LT(static_cast<png_uint_32>(5), png_->width());
    ASSERT_LT(static_cast<png_uint_32>(0), png_->height());
    ASSERT_EQ(1, png_->channels()) << "Recovery background text images expects 1-channel PNG file.";
  }

  std::unique_ptr<PngHandler> png_{ nullptr };
};

// Parses a png file and tests if it's qualified for the background text image under recovery.
TEST_P(ResourcesTest, ValidateLocale) {
  std::vector<unsigned char> row(png_->width());
  for (png_uint_32 y = 0; y < png_->height(); ++y) {
    png_read_row(png_->png_ptr(), row.data(), nullptr);
    int w = (row[1] << 8) | row[0];
    int h = (row[3] << 8) | row[2];
    int len = row[4];
    EXPECT_LT(0, w);
    EXPECT_LT(0, h);
    EXPECT_LT(0, len) << "Locale string should be non-empty.";
    EXPECT_NE(0, row[5]) << "Locale string is missing.";

    ASSERT_GT(png_->height(), y + 1 + h) << "Locale: " << kLocale << " is not found in the file.";
    char* loc = reinterpret_cast<char*>(&row[5]);
    if (matches_locale(loc, kLocale.c_str())) {
      EXPECT_TRUE(android::base::StartsWith(loc, kLocale));
      break;
    }
    for (int i = 0; i < h; ++i, ++y) {
      png_read_row(png_->png_ptr(), row.data(), nullptr);
    }
  }
}

std::vector<std::string> ResourcesTest::png_list = add_files();

INSTANTIATE_TEST_CASE_P(BackgroundTextValidation, ResourcesTest,
                        ::testing::ValuesIn(ResourcesTest::png_list.cbegin(),
                                            ResourcesTest::png_list.cend()));
