// 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 },

    // Blank string encodes as empty string.
    { L" ", 0, 1, L"", 0 },

    // Single 0 should encode as 10 base-900 == 10.
    { L"0", 0, 1, L"", 0 }, // wrong - should be \u000a?

    // 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\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\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\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\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) {

}
