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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
// Original code is licensed as follows:
/*
 * Copyright 2008 ZXing authors
 *
 * 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 "fxbarcode/qrcode/BC_QRCoderMatrixUtil.h"

#include <array>
#include <iterator>

#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
#include "fxbarcode/common/BC_CommonByteMatrix.h"
#include "fxbarcode/qrcode/BC_QRCoder.h"
#include "fxbarcode/qrcode/BC_QRCoderBitVector.h"
#include "fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
#include "fxbarcode/qrcode/BC_QRCoderMaskUtil.h"

namespace {

using PositionDetectionPatternRow = std::array<uint8_t, 7>;
constexpr std::array<const PositionDetectionPatternRow, 7>
    kPositionDetectionPatternTable = {{{{1, 1, 1, 1, 1, 1, 1}},
                                       {{1, 0, 0, 0, 0, 0, 1}},
                                       {{1, 0, 1, 1, 1, 0, 1}},
                                       {{1, 0, 1, 1, 1, 0, 1}},
                                       {{1, 0, 1, 1, 1, 0, 1}},
                                       {{1, 0, 0, 0, 0, 0, 1}},
                                       {{1, 1, 1, 1, 1, 1, 1}}}};

using PositionAdjustmentPatternRow = std::array<uint8_t, 5>;
constexpr std::array<const PositionAdjustmentPatternRow, 5>
    kPositionAdjustmentPatternTable = {{{{1, 1, 1, 1, 1}},
                                        {{1, 0, 0, 0, 1}},
                                        {{1, 0, 1, 0, 1}},
                                        {{1, 0, 0, 0, 1}},
                                        {{1, 1, 1, 1, 1}}}};

constexpr size_t kNumCoordinate = 7;
using PositionCoordinatePatternRow = std::array<uint8_t, kNumCoordinate>;
constexpr std::array<const PositionCoordinatePatternRow, 39>
    kPositionCoordinatePatternTable = {{
        {{6, 18, 0, 0, 0, 0, 0}},         {{6, 22, 0, 0, 0, 0, 0}},
        {{6, 26, 0, 0, 0, 0, 0}},         {{6, 30, 0, 0, 0, 0, 0}},
        {{6, 34, 0, 0, 0, 0, 0}},         {{6, 22, 38, 0, 0, 0, 0}},
        {{6, 24, 42, 0, 0, 0, 0}},        {{6, 26, 46, 0, 0, 0, 0}},
        {{6, 28, 50, 0, 0, 0, 0}},        {{6, 30, 54, 0, 0, 0, 0}},
        {{6, 32, 58, 0, 0, 0, 0}},        {{6, 34, 62, 0, 0, 0, 0}},
        {{6, 26, 46, 66, 0, 0, 0}},       {{6, 26, 48, 70, 0, 0, 0}},
        {{6, 26, 50, 74, 0, 0, 0}},       {{6, 30, 54, 78, 0, 0, 0}},
        {{6, 30, 56, 82, 0, 0, 0}},       {{6, 30, 58, 86, 0, 0, 0}},
        {{6, 34, 62, 90, 0, 0, 0}},       {{6, 28, 50, 72, 94, 0, 0}},
        {{6, 26, 50, 74, 98, 0, 0}},      {{6, 30, 54, 78, 102, 0, 0}},
        {{6, 28, 54, 80, 106, 0, 0}},     {{6, 32, 58, 84, 110, 0, 0}},
        {{6, 30, 58, 86, 114, 0, 0}},     {{6, 34, 62, 90, 118, 0, 0}},
        {{6, 26, 50, 74, 98, 122, 0}},    {{6, 30, 54, 78, 102, 126, 0}},
        {{6, 26, 52, 78, 104, 130, 0}},   {{6, 30, 56, 82, 108, 134, 0}},
        {{6, 34, 60, 86, 112, 138, 0}},   {{6, 30, 58, 86, 114, 142, 0}},
        {{6, 34, 62, 90, 118, 146, 0}},   {{6, 30, 54, 78, 102, 126, 150}},
        {{6, 24, 50, 76, 102, 128, 154}}, {{6, 28, 54, 80, 106, 132, 158}},
        {{6, 32, 58, 84, 110, 136, 162}}, {{6, 26, 54, 82, 110, 138, 166}},
        {{6, 30, 58, 86, 114, 142, 170}},
    }};

struct TypeInfoCoordinate {
  uint8_t x;
  uint8_t y;
};

const std::array<const TypeInfoCoordinate, 15> kTypeInfoCoordinates = {{
    {8, 0},
    {8, 1},
    {8, 2},
    {8, 3},
    {8, 4},
    {8, 5},
    {8, 7},
    {8, 8},
    {7, 8},
    {5, 8},
    {4, 8},
    {3, 8},
    {2, 8},
    {1, 8},
    {0, 8},
}};

constexpr int32_t VERSION_INFO_POLY = 0x1f25;
constexpr int32_t TYPE_INFO_POLY = 0x0537;
constexpr int32_t TYPE_INFO_MASK_PATTERN = 0x5412;

bool IsEmpty(int32_t value) {
  return (uint8_t)value == 0xff;
}

bool IsValidValue(int32_t value) {
  return ((uint8_t)value == 0xff || (uint8_t)value == 0x00 ||
          (uint8_t)value == 0x01);
}

int32_t FindMSBSet(int32_t value) {
  int32_t numDigits = 0;
  while (value != 0) {
    value >>= 1;
    ++numDigits;
  }
  return numDigits;
}

bool EmbedDataBits(CBC_QRCoderBitVector* dataBits,
                   int32_t maskPattern,
                   CBC_CommonByteMatrix* matrix) {
  size_t szBitIndex = 0;
  int32_t direction = -1;
  int32_t x = matrix->GetWidth() - 1;
  int32_t y = matrix->GetHeight() - 1;
  while (x > 0) {
    if (x == 6)
      x -= 1;

    while (y >= 0 && y < static_cast<int32_t>(matrix->GetHeight())) {
      if (y == 6) {
        y += direction;
        continue;
      }
      for (int32_t i = 0; i < 2; i++) {
        int32_t xx = x - i;
        if (!IsEmpty(matrix->Get(xx, y))) {
          continue;
        }
        int32_t bit;
        if (szBitIndex < dataBits->Size()) {
          bit = dataBits->At(szBitIndex);
          szBitIndex++;
        } else {
          bit = 0;
        }
        DCHECK(CBC_QRCoder::IsValidMaskPattern(maskPattern));
        if (CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y))
          bit ^= 0x01;
        matrix->Set(xx, y, bit);
      }
      y += direction;
    }
    direction = -direction;
    y += direction;
    x -= 2;
  }
  return szBitIndex == dataBits->Size();
}

int32_t CalculateBCHCode(int32_t value, int32_t poly) {
  int32_t msbSetInPoly = FindMSBSet(poly);
  value <<= msbSetInPoly - 1;
  while (FindMSBSet(value) >= msbSetInPoly) {
    value ^= poly << (FindMSBSet(value) - msbSetInPoly);
  }
  return value;
}

bool MakeTypeInfoBits(const CBC_QRCoderErrorCorrectionLevel* ecLevel,
                      int32_t maskPattern,
                      CBC_QRCoderBitVector* bits) {
  if (!CBC_QRCoder::IsValidMaskPattern(maskPattern))
    return false;

  int32_t typeInfo = (ecLevel->GetBits() << 3) | maskPattern;
  bits->AppendBits(typeInfo, 5);
  int32_t bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY);
  bits->AppendBits(bchCode, 10);
  CBC_QRCoderBitVector maskBits;
  maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15);
  if (!bits->XOR(&maskBits))
    return false;

  DCHECK_EQ(bits->Size(), 15);
  return true;
}

void MakeVersionInfoBits(int32_t version, CBC_QRCoderBitVector* bits) {
  bits->AppendBits(version, 6);
  int32_t bchCode = CalculateBCHCode(version, VERSION_INFO_POLY);
  bits->AppendBits(bchCode, 12);
  DCHECK_EQ(bits->Size(), 18);
}

bool EmbedTypeInfo(const CBC_QRCoderErrorCorrectionLevel* ecLevel,
                   int32_t maskPattern,
                   CBC_CommonByteMatrix* matrix) {
  CBC_QRCoderBitVector typeInfoBits;
  if (!MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits))
    return false;

  for (size_t i = 0; i < typeInfoBits.Size(); i++) {
    int32_t bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i);
    int32_t x1 = kTypeInfoCoordinates[i].x;
    int32_t y1 = kTypeInfoCoordinates[i].y;
    matrix->Set(x1, y1, bit);
    if (i < 8) {
      int32_t x2 = matrix->GetWidth() - i - 1;
      int32_t y2 = 8;
      matrix->Set(x2, y2, bit);
    } else {
      int32_t x2 = 8;
      int32_t y2 = matrix->GetHeight() - 7 + (i - 8);
      matrix->Set(x2, y2, bit);
    }
  }
  return true;
}

void MaybeEmbedVersionInfo(int32_t version, CBC_CommonByteMatrix* matrix) {
  if (version < 7)
    return;

  CBC_QRCoderBitVector versionInfoBits;
  MakeVersionInfoBits(version, &versionInfoBits);
  int32_t bitIndex = 6 * 3 - 1;
  for (int32_t i = 0; i < 6; i++) {
    for (int32_t j = 0; j < 3; j++) {
      int32_t bit = versionInfoBits.At(bitIndex);
      bitIndex--;
      matrix->Set(i, matrix->GetHeight() - 11 + j, bit);
      matrix->Set(matrix->GetHeight() - 11 + j, i, bit);
    }
  }
}

bool EmbedTimingPatterns(CBC_CommonByteMatrix* matrix) {
  for (size_t i = 8; i + 8 < matrix->GetWidth(); i++) {
    const uint8_t bit = static_cast<uint8_t>((i + 1) % 2);
    if (!IsValidValue(matrix->Get(i, 6)))
      return false;

    if (IsEmpty(matrix->Get(i, 6)))
      matrix->Set(i, 6, bit);

    if (!IsValidValue(matrix->Get(6, i)))
      return false;

    if (IsEmpty(matrix->Get(6, i)))
      matrix->Set(6, i, bit);
  }
  return true;
}

bool EmbedDarkDotAtLeftBottomCorner(CBC_CommonByteMatrix* matrix) {
  if (matrix->Get(8, matrix->GetHeight() - 8) == 0)
    return false;

  matrix->Set(8, matrix->GetHeight() - 8, 1);
  return true;
}

bool EmbedHorizontalSeparationPattern(int32_t xStart,
                                      int32_t yStart,
                                      CBC_CommonByteMatrix* matrix) {
  for (int32_t x = 0; x < 8; x++) {
    if (!IsEmpty(matrix->Get(xStart + x, yStart)))
      return false;

    matrix->Set(xStart + x, yStart, 0);
  }
  return true;
}

bool EmbedVerticalSeparationPattern(int32_t xStart,
                                    int32_t yStart,
                                    CBC_CommonByteMatrix* matrix) {
  for (int32_t y = 0; y < 7; y++) {
    if (!IsEmpty(matrix->Get(xStart, yStart + y)))
      return false;

    matrix->Set(xStart, yStart + y, 0);
  }
  return true;
}

bool EmbedPositionAdjustmentPattern(int32_t xStart,
                                    int32_t yStart,
                                    CBC_CommonByteMatrix* matrix) {
  for (int32_t y = 0; y < 5; y++) {
    for (int32_t x = 0; x < 5; x++) {
      if (!IsEmpty(matrix->Get(xStart + x, y + yStart))) {
        return false;
      }
      matrix->Set(xStart + x, yStart + y,
                  kPositionAdjustmentPatternTable[y][x]);
    }
  }
  return true;
}

bool EmbedPositionDetectionPattern(int32_t xStart,
                                   int32_t yStart,
                                   CBC_CommonByteMatrix* matrix) {
  for (int32_t y = 0; y < 7; y++) {
    for (int32_t x = 0; x < 7; x++) {
      if (!IsEmpty(matrix->Get(xStart + x, yStart + y)))
        return false;

      matrix->Set(xStart + x, yStart + y, kPositionDetectionPatternTable[y][x]);
    }
  }
  return true;
}

bool EmbedPositionDetectionPatternsAndSeparators(CBC_CommonByteMatrix* matrix) {
  constexpr int32_t pdpWidth = 7;
  if (!EmbedPositionDetectionPattern(0, 0, matrix))
    return false;
  if (!EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix))
    return false;
  if (!EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix))
    return false;

  constexpr int32_t hspWidth = 8;
  if (!EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix))
    return false;
  if (!EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth,
                                        hspWidth - 1, matrix)) {
    return false;
  }
  if (!EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth,
                                        matrix)) {
    return false;
  }

  constexpr int32_t vspSize = 7;
  if (!EmbedVerticalSeparationPattern(vspSize, 0, matrix))
    return false;
  if (!EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0,
                                      matrix)) {
    return false;
  }
  if (!EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize,
                                      matrix)) {
    return false;
  }
  return true;
}

bool MaybeEmbedPositionAdjustmentPatterns(int32_t version,
                                          CBC_CommonByteMatrix* matrix) {
  if (version < 2)
    return true;

  const size_t index = version - 2;
  if (index >= std::size(kPositionCoordinatePatternTable)) {
    return false;
  }

  const auto& coordinates = kPositionCoordinatePatternTable[index];
  for (size_t i = 0; i < kNumCoordinate; i++) {
    const int32_t y = coordinates[i];
    if (y == 0)
      break;
    for (size_t j = 0; j < kNumCoordinate; j++) {
      const int32_t x = coordinates[j];
      if (x == 0)
        break;

      if (IsEmpty(matrix->Get(x, y))) {
        if (!EmbedPositionAdjustmentPattern(x - 2, y - 2, matrix))
          return false;
      }
    }
  }
  return true;
}

bool EmbedBasicPatterns(int32_t version, CBC_CommonByteMatrix* matrix) {
  if (!EmbedPositionDetectionPatternsAndSeparators(matrix))
    return false;
  if (!EmbedDarkDotAtLeftBottomCorner(matrix))
    return false;
  if (!MaybeEmbedPositionAdjustmentPatterns(version, matrix))
    return false;
  if (!EmbedTimingPatterns(matrix))
    return false;
  return true;
}

}  // namespace

bool CBC_QRCoderMatrixUtil::BuildMatrix(
    CBC_QRCoderBitVector* dataBits,
    const CBC_QRCoderErrorCorrectionLevel* ecLevel,
    int32_t version,
    int32_t maskPattern,
    CBC_CommonByteMatrix* matrix) {
  if (!dataBits || !matrix)
    return false;

  matrix->Fill(0xff);

  if (!EmbedBasicPatterns(version, matrix))
    return false;
  if (!EmbedTypeInfo(ecLevel, maskPattern, matrix))
    return false;

  MaybeEmbedVersionInfo(version, matrix);
  return EmbedDataBits(dataBits, maskPattern, matrix);
}
