/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 "ByteArrayFixture.hpp"

::testing::AssertionResult ByteArrayFixture::assertByteArrayEqual(
    const char* /*expectedStr*/, const char* /*bytesStr*/, const char* expected,
    const apache::geode::client::ByteArray& bytes) {
  // One would normally just use boost::regex but gcc 4.4.7 is lacking.
  const std::string actual(apache::geode::client::ByteArray::toString(bytes));
  std::string::size_type actualPos = 0;
  const std::string pattern(expected);
  std::string::size_type patternPos = 0;
  while (patternPos < pattern.length()) {
    if (patternPos + 5 <= pattern.length() && '\\' == pattern[patternPos] &&
        'h' == pattern[patternPos + 1] && '{' == pattern[patternPos + 2] &&
        ('0' <= pattern[patternPos + 3] && pattern[patternPos + 3] <= '9')) {
      patternPos += 3;
      std::string::size_type startPos = patternPos;
      while (patternPos < pattern.length() && '}' != pattern[patternPos]) {
        ++patternPos;
      }
      const size_t number =
          std::stoi(pattern.substr(startPos, (patternPos - startPos)));

      auto pos = actual.find_first_not_of("0123456789ABCDEFabcdef", actualPos);
      if (pos == std::string::npos) {
        pos = actual.length();
      }
      if ((pos - actualPos) < number) {
        break;
      }
      actualPos += number;
    } else if (pattern[patternPos] != actual[actualPos++]) {
      break;
    }
    ++patternPos;
  }

  if (patternPos != pattern.length() || actualPos != actual.length()) {
    return ::testing::AssertionFailure() << pattern << " != " << actual;
  }
  return ::testing::AssertionSuccess();
}
