/*
 * Copyright 2019 Xilinx Inc.
 *
 * 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 <vitis/ai/platedetect.hpp>
#include <iostream>
#include <fstream>
#include <memory>
#include <glog/logging.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <cstdlib>
#include <string>
using namespace std;
using namespace vitis::ai;
using namespace cv;

string RESULT_FILE_PATH = "accuracy_result_plate/";

void parseImage(vitis::ai::PlateDetect* det, cv::Mat& img, const std::string& single_name);
std::string get_single_name(const std::string& line);

int main(int argc, char *argv[])
{
    if (argc != 4) {
        cerr << "usage: test_platedetect_accuracy model_name file_list_file_name folder_name" << endl;
        return -1;
    }
    auto det = vitis::ai::PlateDetect::create(argv[1], true);


    RESULT_FILE_PATH = argv[3];
    std::ifstream fs(argv[2]);
    CHECK_EQ(system(string("rm -rf " + string(argv[3])).c_str()), 0);
    CHECK_EQ(system(string("mkdir -p " + string(argv[3])).c_str()), 0);
    std::string line;
    std::string single_name;
    while (getline(fs, line)) {
        // LOG(INFO) << "line = [" << line << "]";
        auto image = cv::imread(line);
        if (image.empty()) {
          cerr << "cannot read image: " << line;
          continue;
        }
        single_name = get_single_name(line);
        cout << single_name << endl;
        parseImage(det.get(), image, single_name);
    }
    fs.close();


    return 0;
}

std::string get_single_name(const std::string& line)
{
   std::size_t found = line.rfind('/');
   if (found != std::string::npos) {
     return line.substr(found+1);
   }
   return line;
}

static std::vector<std::string> split(const std::string &s,
                                      const std::string &delim) {
  std::vector<std::string> elems;
  size_t pos = 0;
  size_t len = s.length();
  size_t delim_len = delim.length();
  if (delim_len == 0)
    return elems;
  while (pos < len) {
    int find_pos = s.find(delim, pos);
    if (find_pos < 0) {
      elems.push_back(s.substr(pos, len - pos));
      break;
    }
    elems.push_back(s.substr(pos, find_pos - pos));
    pos = find_pos + delim_len;
  }
  return elems;
}

void parseImage(vitis::ai::PlateDetect* det, cv::Mat& img, const std::string& single_name)
{
    int width = det->getInputWidth();
    int height = det->getInputHeight();

    cv::Mat img_resize;
    cv::resize(img, img_resize, cv::Size(width, height), 0, 0,
               cv::INTER_LINEAR);

    auto result = det->run(img);

    // there is no label here, we always use "1" to comply with standard result format
    // std::cout << single_name << " 1 " << result.box.score << " "
    ofstream out(RESULT_FILE_PATH + "/" + split(single_name, ".")[0] + ".txt");
    out << result.top_left.x *img.cols << " "
              << result.top_left.y *img.rows << " "
              << result.top_right.x *img.cols << " "
              << result.top_right.y *img.rows << " "
              << result.bottom_right.x *img.cols << " "
              << result.bottom_right.y *img.rows << " " 
              << result.bottom_left.x *img.cols << " "
              << result.bottom_left.y *img.rows << " " << std::endl;
    out.close();
}
