/*
 * Copyright 2023 Google LLC
 *
 * 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 "tests/cv/extrema.h"

#include <cstdint>
#include <cstdio>

#include "crt/kelvin.h"
#include "tests/cv/test_helper.h"

enum kMode { kNone, kMinimum, kMaximum };

template <typename TComparisonOp>
bool IsPointExtrema(const int16_t *input[4][3], int layer_id, int col,
                    TComparisonOp comparison_op) {
  const int16_t center_value = input[layer_id][1][col];
  for (int layer_id_offset = -1; layer_id_offset <= 1; layer_id_offset++) {
    for (int row_id = 0; row_id < 3; row_id++) {
      for (int col_offset = -1; col_offset <= 1; col_offset++) {
        // Do not compare to input[layer_id][1][col] which is value.
        if (layer_id_offset == 0 && row_id == 1 && col_offset == 0) {
          continue;
        }
        if (!comparison_op(
                center_value,
                input[layer_id + layer_id_offset][row_id][col + col_offset])) {
          return false;
        }
      }
    }
  }
  return true;
}

void Extrema(int num_cols, const int16_t *input[4][3], uint8_t *output0,
             uint8_t *output1) {
  auto max_comp = [](int x, int y) { return x > y; };
  auto min_comp = [](int x, int y) { return x < y; };

  // Update extrema for layer 1.
  for (int col = 1; col < num_cols - 1; col++) {
    output0[col] = kMode::kNone;
    if (IsPointExtrema(input, 1, col, max_comp)) {
      output0[col] = kMaximum;
      continue;
    }
    if (IsPointExtrema(input, 1, col, min_comp)) {
      output0[col] = kMode::kMinimum;
    }
  }

  // Update extrema for layer 2.
  for (int col = 1; col < num_cols - 1; col++) {
    output1[col] = kMode::kNone;
    if (IsPointExtrema(input, 2, col, max_comp)) {
      output1[col] = kMode::kMaximum;
      continue;
    }
    if (IsPointExtrema(input, 2, col, min_comp)) {
      output1[col] = kMode::kMinimum;
    }
  }
}

void extrema_test() {
  constexpr int kNumCols = 640;

  int16_t input0_row0[kNumCols] __attribute__((aligned(64)));
  int16_t input0_row1[kNumCols] __attribute__((aligned(64)));
  int16_t input0_row2[kNumCols] __attribute__((aligned(64)));
  int16_t input1_row0[kNumCols] __attribute__((aligned(64)));
  int16_t input1_row1[kNumCols] __attribute__((aligned(64)));
  int16_t input1_row2[kNumCols] __attribute__((aligned(64)));
  int16_t input2_row0[kNumCols] __attribute__((aligned(64)));
  int16_t input2_row1[kNumCols] __attribute__((aligned(64)));
  int16_t input2_row2[kNumCols] __attribute__((aligned(64)));
  int16_t input3_row0[kNumCols] __attribute__((aligned(64)));
  int16_t input3_row1[kNumCols] __attribute__((aligned(64)));
  int16_t input3_row2[kNumCols] __attribute__((aligned(64)));

  uint8_t output0_ref[kNumCols];
  uint8_t output1_ref[kNumCols];
  uint8_t output0_dut[kNumCols];
  uint8_t output1_dut[kNumCols];

  const int16_t *input[4][3] = {{reinterpret_cast<int16_t *>(input0_row0),
                                 reinterpret_cast<int16_t *>(input0_row1),
                                 reinterpret_cast<int16_t *>(input0_row2)},
                                {reinterpret_cast<int16_t *>(input1_row0),
                                 reinterpret_cast<int16_t *>(input1_row1),
                                 reinterpret_cast<int16_t *>(input1_row2)},
                                {reinterpret_cast<int16_t *>(input2_row0),
                                 reinterpret_cast<int16_t *>(input2_row1),
                                 reinterpret_cast<int16_t *>(input2_row2)},
                                {reinterpret_cast<int16_t *>(input3_row0),
                                 reinterpret_cast<int16_t *>(input3_row1),
                                 reinterpret_cast<int16_t *>(input3_row2)}};

  krand(kNumCols, input0_row0);
  krand(kNumCols, input0_row1);
  krand(kNumCols, input0_row2);
  krand(kNumCols, input1_row0);
  krand(kNumCols, input1_row1);
  krand(kNumCols, input1_row2);
  krand(kNumCols, input2_row0);
  krand(kNumCols, input2_row1);
  krand(kNumCols, input2_row2);
  krand(kNumCols, input3_row0);
  krand(kNumCols, input3_row1);
  krand(kNumCols, input3_row2);

  Extrema(kNumCols, input, output0_ref, output1_ref);

  kelvin::cv::extrema(kNumCols, input, output0_dut, output1_dut);

  for (int i = 1; i < kNumCols - 1; ++i) {
    const uint8_t ref = output0_ref[i];
    const uint8_t dut = output0_dut[i];
    if (ref != dut) {
      printf("**error::extrema0[%d] %x %x\n", i, ref, dut);
      exit(1);
    }
  }

  for (int i = 1; i < kNumCols - 1; ++i) {
    const uint8_t ref = output1_ref[i];
    const uint8_t dut = output1_dut[i];
    if (ref != dut) {
      printf("**error::extrema1[%d] %x %x\n", i, ref, dut);
      exit(1);
    }
  }
}

int main() {
  extrema_test();
  return 0;
}
