// Copyright 2019 Google LLC
//
// 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
//
//      https://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 "hal/buffer_view_string_util.h"

#include "base/status.h"
#include "base/status_matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace iree {
namespace hal {
namespace {

using ::testing::ElementsAre;

template <typename T>
StatusOr<std::vector<T>> ReadBuffer(const ref_ptr<Buffer>& buffer) {
  std::vector<T> result;
  result.resize(buffer->byte_length() / sizeof(T));
  RETURN_IF_ERROR(
      buffer->ReadData(0, result.data(), result.size() * sizeof(T)));
  return result;
}

TEST(BufferViewUtilTest, GetTypeElementSize) {
  EXPECT_EQ(1, GetTypeElementSize("1").ValueOrDie());
  EXPECT_EQ(7, GetTypeElementSize("7").ValueOrDie());
  EXPECT_EQ(4, GetTypeElementSize("i32").ValueOrDie());
  EXPECT_EQ(8, GetTypeElementSize("f64").ValueOrDie());

  EXPECT_FALSE(GetTypeElementSize("").ok());
  EXPECT_FALSE(GetTypeElementSize(" ").ok());
  EXPECT_FALSE(GetTypeElementSize("a").ok());
  EXPECT_FALSE(GetTypeElementSize("ib").ok());
  EXPECT_FALSE(GetTypeElementSize("i").ok());
  EXPECT_FALSE(GetTypeElementSize("i543ff").ok());
}

TEST(BufferViewUtilTest, ParseShape) {
  EXPECT_EQ((Shape{}), ParseShape("").ValueOrDie());
  EXPECT_EQ((Shape{1}), ParseShape("1").ValueOrDie());
  EXPECT_EQ((Shape{1, 2}), ParseShape("1x2").ValueOrDie());
  EXPECT_EQ((Shape{1, 2}), ParseShape(" 1 x 2 ").ValueOrDie());

  EXPECT_FALSE(ParseShape("abc").ok());
  EXPECT_FALSE(ParseShape("1xf").ok());
  EXPECT_FALSE(ParseShape("1xff23").ok());
}

TEST(BufferViewUtilTest, ParseBufferViewFromStringEmpty) {
  // Empty string = empty buffer_view.
  ASSERT_OK_AND_ASSIGN(auto m0, ParseBufferViewFromString(""));
  EXPECT_EQ(nullptr, m0.buffer.get());
  EXPECT_EQ(Shape{}, m0.shape);
  EXPECT_EQ(0, m0.element_size);

  // No = means no data.
  ASSERT_OK_AND_ASSIGN(auto m1, ParseBufferViewFromString("4x2xf32"));
  EXPECT_EQ(4 * 2 * 4, m1.buffer->allocation_size());
  EXPECT_EQ(Shape({4, 2}), m1.shape);
  EXPECT_EQ(4, m1.element_size);
  EXPECT_THAT(ReadBuffer<float>(m1.buffer).ValueOrDie(),
              ElementsAre(0, 0, 0, 0, 0, 0, 0, 0));

  // No data after = means no data.
  ASSERT_OK_AND_ASSIGN(auto m2, ParseBufferViewFromString("4x2xf32="));
  EXPECT_EQ(4 * 2 * 4, m2.buffer->allocation_size());
  EXPECT_EQ(Shape({4, 2}), m2.shape);
  EXPECT_EQ(4, m2.element_size);
  EXPECT_THAT(ReadBuffer<float>(m2.buffer).ValueOrDie(),
              ElementsAre(0, 0, 0, 0, 0, 0, 0, 0));
}

TEST(BufferViewUtilTest, ParseBufferViewFromStringBinary) {
  ASSERT_OK_AND_ASSIGN(auto m0, ParseBufferViewFromString("4x1=00 01 02 03"));
  EXPECT_EQ(Shape({4}), m0.shape);
  EXPECT_EQ(1, m0.element_size);
  EXPECT_THAT(ReadBuffer<uint8_t>(m0.buffer).ValueOrDie(),
              ElementsAre(0, 1, 2, 3));

  // Whitespace shouldn't matter.
  ASSERT_OK_AND_ASSIGN(auto m1, ParseBufferViewFromString("4x1=00,010203"));
  EXPECT_EQ(Shape({4}), m1.shape);
  EXPECT_EQ(1, m1.element_size);
  EXPECT_THAT(ReadBuffer<uint8_t>(m1.buffer).ValueOrDie(),
              ElementsAre(0, 1, 2, 3));

  // Should fail on malformed hex bytes.
  EXPECT_FALSE(ParseBufferViewFromString("4x1=1").ok());
  EXPECT_FALSE(ParseBufferViewFromString("4x1=00003").ok());
  EXPECT_FALSE(ParseBufferViewFromString("4x1=%0123%\1").ok());
  EXPECT_FALSE(ParseBufferViewFromString("4x1=00010203040506").ok());
}

TEST(BufferViewUtilTest, ParseBufferViewFromStringAllowBrackets) {
  ASSERT_OK_AND_ASSIGN(auto m0,
                       ParseBufferViewFromString("4xi16=[[0][ 1 ][2]][3]"));
  EXPECT_EQ(Shape({4}), m0.shape);
  EXPECT_EQ(2, m0.element_size);
  EXPECT_THAT(ReadBuffer<int16_t>(m0.buffer).ValueOrDie(),
              ElementsAre(0, 1, 2, 3));
}

TEST(BufferViewUtilTest, ParseBufferViewFromStringInteger) {
  // Signed int16.
  ASSERT_OK_AND_ASSIGN(auto m0,
                       ParseBufferViewFromString("4xi16=0 12345 65535 -2"));
  EXPECT_EQ(Shape({4}), m0.shape);
  EXPECT_EQ(2, m0.element_size);
  EXPECT_THAT(ReadBuffer<int16_t>(m0.buffer).ValueOrDie(),
              ElementsAre(0, 12345, -1, -2));

  // Unsigned int16.
  ASSERT_OK_AND_ASSIGN(auto m1,
                       ParseBufferViewFromString("4xu16=0 12345 65535 -2"));
  EXPECT_EQ(Shape({4}), m1.shape);
  EXPECT_EQ(2, m1.element_size);
  EXPECT_THAT(ReadBuffer<uint16_t>(m1.buffer).ValueOrDie(),
              ElementsAre(0, 12345, 65535, 65534));

  // Mixing separator types is ok.
  ASSERT_OK_AND_ASSIGN(auto m2,
                       ParseBufferViewFromString("4xu16=0, 12345, 65535, -2"));
  EXPECT_EQ(Shape({4}), m2.shape);
  EXPECT_EQ(2, m2.element_size);
  EXPECT_THAT(ReadBuffer<uint16_t>(m2.buffer).ValueOrDie(),
              ElementsAre(0, 12345, 65535, 65534));

  // Should fail on malformed integers bytes and out of bounds values.
  EXPECT_FALSE(ParseBufferViewFromString("4xi32=asodfj").ok());
  EXPECT_FALSE(ParseBufferViewFromString("4xi32=0 1 2 3 4").ok());
}

TEST(BufferViewUtilTest, ParseBufferViewFromStringFloat) {
  // Float.
  ASSERT_OK_AND_ASSIGN(auto m0,
                       ParseBufferViewFromString("4xf32=0 1.0 1234 -2.0e-5"));
  EXPECT_EQ(Shape({4}), m0.shape);
  EXPECT_EQ(4, m0.element_size);
  EXPECT_THAT(ReadBuffer<float>(m0.buffer).ValueOrDie(),
              ElementsAre(0.0f, 1.0f, 1234.0f, -2.0e-5f));

  // Double.
  ASSERT_OK_AND_ASSIGN(auto m1, ParseBufferViewFromString(
                                    "4xf64=0 1.0 123456789012345 -2.0e-5"));
  EXPECT_EQ(Shape({4}), m1.shape);
  EXPECT_EQ(8, m1.element_size);
  EXPECT_THAT(ReadBuffer<double>(m1.buffer).ValueOrDie(),
              ElementsAre(0.0, 1.0, 123456789012345.0, -2.0e-5));

  // Should fail on malformed floats and out of bounds values.
  EXPECT_FALSE(ParseBufferViewFromString("4xf32=asodfj").ok());
  EXPECT_FALSE(ParseBufferViewFromString("4xf32=0").ok());
  EXPECT_FALSE(ParseBufferViewFromString("4xf32=0 1 2 3 4").ok());
}

TEST(BufferViewUtilTest, ParseBufferViewPrintMode) {
  EXPECT_EQ(BufferViewPrintMode::kBinary,
            ParseBufferViewPrintMode("b").ValueOrDie());
  EXPECT_EQ(BufferViewPrintMode::kSignedInteger,
            ParseBufferViewPrintMode("i").ValueOrDie());
  EXPECT_EQ(BufferViewPrintMode::kUnsignedInteger,
            ParseBufferViewPrintMode("u").ValueOrDie());
  EXPECT_EQ(BufferViewPrintMode::kFloatingPoint,
            ParseBufferViewPrintMode("f").ValueOrDie());

  EXPECT_FALSE(ParseBufferViewPrintMode("").ok());
  EXPECT_FALSE(ParseBufferViewPrintMode("s").ok());
  EXPECT_FALSE(ParseBufferViewPrintMode("asdfasdf").ok());
}

}  // namespace
}  // namespace hal
}  // namespace iree
