// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "testing/gtest/include/gtest/gtest.h"
#include "core/include/fxcrt/fx_basic.h"
#include "testing/fx_string_testhelpers.h"
#include "BC_PDF417HighLevelEncoder.h"

TEST(PDF417HighLevelEncoder, EncodeHighLevel) {
  // TODO(tsepez): implement test cases.
}

TEST(PDF417HighLevelEncoder, EncodeText) {
  // TODO(tsepez): implement test cases.
}

TEST(PDF417HighLevelEncoder, EncodeBinary) {
  struct EncodeBinaryCase {
    const char* input;
    int offset;
    int count;
    int startmode;
    const wchar_t* expected;
    int expected_length;
  } encode_binary_cases[] = {
      // Empty string encodes as empty string.
      {"", 0, 0, CBC_PDF417HighLevelEncoder::TEXT_COMPACTION, L"", 0},

      // Fewer than 6 characters encodes as prefix without compaction.
      {"xxxxx", 0, 5, CBC_PDF417HighLevelEncoder::TEXT_COMPACTION,
       L"\x0385xxxxx", 6},

      // 6 charcters triggerst text encoding compaction.
      {"xxxxxx", 0, 6, CBC_PDF417HighLevelEncoder::TEXT_COMPACTION,
       L"\u039c\u00c9\u031f\u012a\u00d2\u02d0", 6},

      // Same result if initially in numeric compaction mode.
      {"xxxxxx", 0, 6, CBC_PDF417HighLevelEncoder::NUMERIC_COMPACTION,
       L"\u039c\u00c9\u031f\u012a\u00d2\u02d0", 6},
  };

  CBC_PDF417HighLevelEncoder::Initialize();
  for (size_t i = 0; i < FX_ArraySize(encode_binary_cases); ++i) {
    EncodeBinaryCase* ptr = &encode_binary_cases[i];
    CFX_ByteArray input_array;
    size_t input_length = strlen(ptr->input);
    input_array.SetSize(input_length);
    for (size_t j = 0; j < input_length; ++j) {
      input_array.SetAt(j, ptr->input[j]);
    }
    CFX_WideString expected(ptr->expected, ptr->expected_length);
    CFX_WideString result;
    CBC_PDF417HighLevelEncoder::encodeBinary(
        &input_array, ptr->offset, ptr->count, ptr->startmode, result);
    EXPECT_EQ(expected, result) << " for case number " << i;
  }
  CBC_PDF417HighLevelEncoder::Finalize();
}

TEST(PDF417HighLevelEncoder, EncodeNumeric) {
  struct EncodeNumericCase {
    const wchar_t* input;
    int offset;
    int count;
    const wchar_t* expected;
    int expected_length;
  } encode_numeric_cases[] = {
      // Empty string encodes as empty string.
      {L"", 0, 0, L"", 0},

      // Single 0 should encode as 10 base-900 == a.
      {L"0", 0, 1, L"\x000a", 1},

      // 800 should encode as 1800 base-900 == 2,0.
      {L"800", 0, 3, L"\x0002\x0000", 2},

      // Test longer strings and sub-strings.
      {L"123456", 0, 6, L"\x0001\x015c\x0100", 3},
      {L"123456", 0, 5, L"\x007c\x02e9", 2},
      {L"123456", 1, 5, L"\x0089\x009c", 2},
      {L"123456", 2, 2, L"\x0086", 1},

      // Up to 44 characters encodes as 15 base-900 words.
      {L"00000000000000000000000000000000000000000000",
       0,
       44,
       L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
       L"\x0090\x020b\x019b\x0064",
       15},

      // 45 characters should encode as same 15 words followed by one additional
      // word.
      {L"000000000000000000000000000000000000000000000",
       0,
       45,
       L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
       L"\x0090\x020b\x019b\x0064\x000a",
       16},

      // 44 characters followed by 800 should encode as 15 words followed by
      // 1800 base-900 == 2,0.
      {L"00000000000000000000000000000000000000000000800",
       0,
       47,
       L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
       L"\x0090\x020b\x019b\x0064\x0002\x0000",
       17},

      // Even longer input.
      {L"10000000000000000000000000000000000000000000000000",
       0,
       50,
       L"\x01e0\x02f0\x036d\x02ad\x029c\x01ea\x0011\x000b\x02d6\x023c\x0108"
       L"\x02bb\x0023\x02d2\x00c8\x0001\x00d3\x0064",
       18},
  };

  CBC_PDF417HighLevelEncoder::Initialize();
  for (size_t i = 0; i < FX_ArraySize(encode_numeric_cases); ++i) {
    EncodeNumericCase* ptr = &encode_numeric_cases[i];
    CFX_WideString input(ptr->input);
    CFX_WideString expected(ptr->expected, ptr->expected_length);
    CFX_WideString result;
    CBC_PDF417HighLevelEncoder::encodeNumeric(input, ptr->offset, ptr->count,
                                              result);
    EXPECT_EQ(expected, result) << " for case number " << i;
  }
  CBC_PDF417HighLevelEncoder::Finalize();
}

TEST(PDF417HighLevelEncoder, ConsecutiveDigitCount) {
  struct ConsecutiveDigitCase {
    const wchar_t* input;
    int offset;
    int expected_count;
  } consecutive_digit_cases[] = {
      // Empty string contains 0 consecuitve digits.
      {L"", 0, 0},

      // Single non-digit character contains 0 consecutive digits.
      {L"X", 0, 0},

      // Leading non-digit followed by digits contains 0 consecutive.
      {L"X123", 0, 0},

      // Single digit contains 1 consecutive digit.
      {L"1", 0, 1},

      // Single digit followe by non-digit contains 1 consecutive digit.
      {L"1Z", 0, 1},

      // Test longer strings.
      {L"123FOO45678", 0, 3},

      // Test subtring starting in digits field.
      {L"123FOO45678", 3, 0},

      // Test subtring starting in non-digits field.
      {L"123FOO45678", 3, 0},

      // Test substring starting in digits field following non-digit field.
      {L"123FOO45678", 6, 5},
  };

  CBC_PDF417HighLevelEncoder::Initialize();
  for (size_t i = 0; i < FX_ArraySize(consecutive_digit_cases); ++i) {
    ConsecutiveDigitCase* ptr = &consecutive_digit_cases[i];
    CFX_WideString input(ptr->input);
    int actual_count =
        CBC_PDF417HighLevelEncoder::determineConsecutiveDigitCount(input,
                                                                   ptr->offset);
    EXPECT_EQ(ptr->expected_count, actual_count) << " for case number " << i;
  }
  CBC_PDF417HighLevelEncoder::Finalize();
}

TEST(PDF417HighLevelEncoder, ConsecutiveTextCount) {
  struct ConsecutiveTextCase {
    const wchar_t* input;
    int offset;
    int expected_count;
  } consecutive_text_cases[] = {
      // Empty string contains 0 consecutive text characters.
      {L"", 0, 0},

      // Single text character is 1 consecutive text characters.
      {L"X", 0, 1},

      // Trailing numbers count as text characters.
      {L"X123", 0, 4},

      // Leading numbers count as text characters.
      {L"123X", 0, 4},

      // Embedded lo-value binary characters terminate text runs.
      {L"ABC\x0001XXXX", 0, 3},

      // Embedded hi-value binary characters terminate text runs.
      {L"ABC\x0100XXXX", 0, 3},

      // Text run still found after indexing past lo-value character.
      {L"ABC\x0001XXXX", 4, 4},

      // Text run still found after indexing past hi-value character.
      {L"ABC\x0100XXXX", 4, 4},

      // Leading hi-value character results in 0 consecutive characters.
      {L"\x0100XXX", 0, 0},

      // Up to 12 numbers count as text.
      {L"123456789012", 0, 12},

      // 13 or more numbers are compresssed using numeric compression, not text.
      {L"1234567890123", 0, 0},

      // Leading Text character doesn't affect the 12 character case.
      {L"X123456789012", 0, 13},

      // Leading Text character doesn't affect the 13 character case.
      {L"X1234567890123", 0, 1},

      // Jumping between numbers and letters works properly.
      {L"XXX121XXX12345678901234", 0, 9},
  };

  CBC_PDF417HighLevelEncoder::Initialize();
  for (size_t i = 0; i < FX_ArraySize(consecutive_text_cases); ++i) {
    ConsecutiveTextCase* ptr = &consecutive_text_cases[i];
    CFX_WideString input(ptr->input);
    int actual_count =
        CBC_PDF417HighLevelEncoder::determineConsecutiveTextCount(input,
                                                                  ptr->offset);
    EXPECT_EQ(ptr->expected_count, actual_count) << " for case number " << i;
  }
  CBC_PDF417HighLevelEncoder::Finalize();
}

TEST(PDF417HighLevelEncoder, ConsecutiveBinaryCount) {}
