// Copyright 2017 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 "fxbarcode/cfx_barcode.h"

#include <memory>
#include <string>
#include <utility>

#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/utils/bitmap_saver.h"
#include "testing/utils/hash.h"

class BarcodeTest : public testing::Test {
 public:
  void SetUp() override {
    BC_Library_Init();

    auto device = std::make_unique<CFX_DefaultRenderDevice>();
    auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
    if (bitmap->Create(640, 480, FXDIB_Format::kRgb32))
      bitmap_ = bitmap;
    ASSERT_TRUE(bitmap_);
    ASSERT_TRUE(device->Attach(bitmap_, false, nullptr, false));
    device_ = std::move(device);
  }

  void TearDown() override {
    bitmap_.Reset();
    device_.reset();
    barcode_.reset();
    BC_Library_Destroy();
  }

  CFX_Barcode* barcode() const { return barcode_.get(); }

  void Create(BC_TYPE type) {
    barcode_ = CFX_Barcode::Create(type);
    barcode_->SetHeight(298);
    barcode_->SetWidth(418);
  }

  bool RenderDevice() { return barcode_->RenderDevice(device_.get(), matrix_); }

  std::string BitmapChecksum() {
    return GenerateMD5Base16(bitmap_->GetBuffer(),
                             bitmap_->GetPitch() * bitmap_->GetHeight());
  }

  // Manually insert calls to this as needed for debugging.
  void SaveBitmap(const std::string& filename) {
    BitmapSaver::WriteBitmapToPng(bitmap_.Get(), filename);
  }

 protected:
  CFX_Matrix matrix_;
  std::unique_ptr<CFX_Barcode> barcode_;
  std::unique_ptr<CFX_RenderDevice> device_;
  RetainPtr<CFX_DIBitmap> bitmap_;
};

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_Code39 DISABLED_Code39
#else
#define MAYBE_Code39 Code39
#endif
TEST_F(BarcodeTest, MAYBE_Code39) {
  Create(BC_CODE39);
  EXPECT_TRUE(barcode()->Encode(L"CLAMS"));
  RenderDevice();
  EXPECT_EQ("cd4cd3f36da38ff58d9f621827018903", BitmapChecksum());
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_CodaBar DISABLED_CodaBar
#else
#define MAYBE_CodaBar CodaBar
#endif
TEST_F(BarcodeTest, MAYBE_CodaBar) {
  Create(BC_CODABAR);
  EXPECT_TRUE(barcode()->Encode(L"$123-456"));
  RenderDevice();
  EXPECT_EQ("5fad4fc19f099001a0fe83c89430c977", BitmapChecksum());
}

TEST_F(BarcodeTest, CodaBarLetters) {
  Create(BC_CODABAR);
  EXPECT_FALSE(barcode()->Encode(L"clams"));
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_Code128 DISABLED_Code128
#else
#define MAYBE_Code128 Code128
#endif
TEST_F(BarcodeTest, MAYBE_Code128) {
  Create(BC_CODE128);
  EXPECT_TRUE(barcode()->Encode(L"Clams"));
  RenderDevice();
  EXPECT_EQ("6351f0f6e997050e4658bbb4777aef74", BitmapChecksum());
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_Code128B DISABLED_Code128B
#else
#define MAYBE_Code128B Code128B
#endif
TEST_F(BarcodeTest, MAYBE_Code128B) {
  Create(BC_CODE128_B);
  EXPECT_TRUE(barcode()->Encode(L"Clams"));
  RenderDevice();
  EXPECT_EQ("6351f0f6e997050e4658bbb4777aef74", BitmapChecksum());
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_Code128C DISABLED_Code128C
#else
#define MAYBE_Code128C Code128C
#endif
TEST_F(BarcodeTest, MAYBE_Code128C) {
  Create(BC_CODE128_C);
  EXPECT_TRUE(barcode()->Encode(L"123456"));
  RenderDevice();
  EXPECT_EQ("fba730a807ba6363f9bd2bc7f8c56d1f", BitmapChecksum());
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_Code128CLetters DISABLED_Code128CLetters
#else
#define MAYBE_Code128CLetters Code128CLetters
#endif
TEST_F(BarcodeTest, MAYBE_Code128CLetters) {
  Create(BC_CODE128_C);
  EXPECT_TRUE(barcode()->Encode(L"clams"));
  RenderDevice();
  EXPECT_EQ("6284ec8503d5a948c9518108da33cdd3", BitmapChecksum());
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_Ean8 DISABLED_Ean8
#else
#define MAYBE_Ean8 Ean8
#endif
TEST_F(BarcodeTest, MAYBE_Ean8) {
  Create(BC_EAN8);
  EXPECT_TRUE(barcode()->Encode(L"123456"));
  RenderDevice();
  EXPECT_EQ("aff88491ac46ca6217d780d185300cde", BitmapChecksum());
}

TEST_F(BarcodeTest, Ean8Letters) {
  Create(BC_EAN8);
  EXPECT_FALSE(barcode()->Encode(L"clams"));
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_UPCA DISABLED_UPCA
#else
#define MAYBE_UPCA UPCA
#endif
TEST_F(BarcodeTest, MAYBE_UPCA) {
  Create(BC_UPCA);
  EXPECT_TRUE(barcode()->Encode(L"123456"));
  RenderDevice();
  EXPECT_EQ("fe26a5714cff7ffe3f9b02183efc435b", BitmapChecksum());
}

TEST_F(BarcodeTest, UPCALetters) {
  Create(BC_UPCA);
  EXPECT_FALSE(barcode()->Encode(L"clams"));
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_Ean13 DISABLED_Ean13
#else
#define MAYBE_Ean13 Ean13
#endif
TEST_F(BarcodeTest, MAYBE_Ean13) {
  Create(BC_EAN13);
  EXPECT_TRUE(barcode()->Encode(L"123456"));
  RenderDevice();
  EXPECT_EQ("72d2190b98d635c32834bf67552e561e", BitmapChecksum());
}

TEST_F(BarcodeTest, Ean13Letters) {
  Create(BC_EAN13);
  EXPECT_FALSE(barcode()->Encode(L"clams"));
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_Pdf417 DISABLED_Pdf417
#else
#define MAYBE_Pdf417 Pdf417
#endif
TEST_F(BarcodeTest, MAYBE_Pdf417) {
  Create(BC_PDF417);
  EXPECT_TRUE(barcode()->Encode(L"clams"));
  RenderDevice();
  EXPECT_EQ("191e35d11613901b7d5d51033689aa89", BitmapChecksum());
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_DataMatrix DISABLED_DataMatrix
#else
#define MAYBE_DataMatrix DataMatrix
#endif
TEST_F(BarcodeTest, MAYBE_DataMatrix) {
  Create(BC_DATAMATRIX);
  EXPECT_TRUE(barcode()->Encode(L"clams"));
  RenderDevice();
  EXPECT_EQ("5e5cd9a680b86fcd4ffd53ed36e3c980", BitmapChecksum());
}

// https://crbug.com/pdfium/738
#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
#define MAYBE_QrCode DISABLED_QrCode
#else
#define MAYBE_QrCode QrCode
#endif
TEST_F(BarcodeTest, MAYBE_QrCode) {
  Create(BC_QR_CODE);
  EXPECT_TRUE(barcode()->Encode(L"clams"));
  RenderDevice();
  EXPECT_EQ("4751c6e0f67749fabe24f787128decee", BitmapChecksum());
}
