// Copyright (c) 2017 Pierre Moreau
//
// 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 "gmock/gmock.h"
#include "linker_fixture.h"

namespace {

using ::testing::HasSubstr;

class EntryPoints : public spvtest::LinkerTest {
 public:
  EntryPoints() { binaries.reserve(0xFFFF); }

  virtual void SetUp() override {
    binaries.push_back({SpvMagicNumber,
                        SpvVersion,
                        SPV_GENERATOR_CODEPLAY,
                        10u,  // NOTE: Bound
                        0u,   // NOTE: Schema; reserved

                        3u << SpvWordCountShift | SpvOpTypeFloat,
                        1u,   // NOTE: Result ID
                        32u,  // NOTE: Width

                        4u << SpvWordCountShift | SpvOpTypePointer,
                        2u,  // NOTE: Result ID
                        SpvStorageClassInput,
                        1u,  // NOTE: Type ID

                        2u << SpvWordCountShift | SpvOpTypeVoid,
                        3u,  // NOTE: Result ID

                        3u << SpvWordCountShift | SpvOpTypeFunction,
                        4u,  // NOTE: Result ID
                        3u,  // NOTE: Return type

                        5u << SpvWordCountShift | SpvOpFunction,
                        3u,  // NOTE: Result type
                        5u,  // NOTE: Result ID
                        SpvFunctionControlMaskNone,
                        4u,  // NOTE: Function type

                        2u << SpvWordCountShift | SpvOpLabel,
                        6u,  // NOTE: Result ID

                        4u << SpvWordCountShift | SpvOpVariable,
                        2u,  // NOTE: Type ID
                        7u,  // NOTE: Result ID
                        SpvStorageClassFunction,

                        4u << SpvWordCountShift | SpvOpVariable,
                        2u,  // NOTE: Type ID
                        8u,  // NOTE: Result ID
                        SpvStorageClassFunction,

                        4u << SpvWordCountShift | SpvOpVariable,
                        2u,  // NOTE: Type ID
                        9u,  // NOTE: Result ID
                        SpvStorageClassFunction,

                        1u << SpvWordCountShift | SpvOpReturn,

                        1u << SpvWordCountShift | SpvOpFunctionEnd});
    for (size_t i = 0u; i < 2u; ++i) {
      spvtest::Binary binary = {
          SpvMagicNumber,
          SpvVersion,
          SPV_GENERATOR_CODEPLAY,
          103u,  // NOTE: Bound
          0u,    // NOTE: Schema; reserved

          3u << SpvWordCountShift | SpvOpTypeFloat,
          1u,   // NOTE: Result ID
          32u,  // NOTE: Width

          4u << SpvWordCountShift | SpvOpTypePointer,
          2u,  // NOTE: Result ID
          SpvStorageClassInput,
          1u  // NOTE: Type ID
      };

      for (uint32_t j = 0u; j < 0xFFFFu / 2u; ++j) {
        binary.push_back(4u << SpvWordCountShift | SpvOpVariable);
        binary.push_back(2u);      // NOTE: Type ID
        binary.push_back(j + 3u);  // NOTE: Result ID
        binary.push_back(SpvStorageClassInput);
      }
      binaries.push_back(binary);
    }
  }
  virtual void TearDown() override { binaries.clear(); }

  spvtest::Binaries binaries;
};

TEST_F(EntryPoints, UnderLimit) {
  spvtest::Binary linked_binary;

  ASSERT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary));
  EXPECT_THAT(GetErrorMessage(), std::string());
}

TEST_F(EntryPoints, OverLimit) {
  binaries.push_back({SpvMagicNumber,
                      SpvVersion,
                      SPV_GENERATOR_CODEPLAY,
                      5u,  // NOTE: Bound
                      0u,  // NOTE: Schema; reserved

                      3u << SpvWordCountShift | SpvOpTypeFloat,
                      1u,   // NOTE: Result ID
                      32u,  // NOTE: Width

                      4u << SpvWordCountShift | SpvOpTypePointer,
                      2u,  // NOTE: Result ID
                      SpvStorageClassInput,
                      1u,  // NOTE: Type ID

                      4u << SpvWordCountShift | SpvOpVariable,
                      2u,  // NOTE: Type ID
                      3u,  // NOTE: Result ID
                      SpvStorageClassInput,

                      4u << SpvWordCountShift | SpvOpVariable,
                      2u,  // NOTE: Type ID
                      4u,  // NOTE: Result ID
                      SpvStorageClassInput});

  spvtest::Binary linked_binary;

  ASSERT_EQ(SPV_ERROR_INTERNAL, Link(binaries, &linked_binary));
  EXPECT_THAT(GetErrorMessage(),
              HasSubstr("The limit of global values, 65535, was exceeded; "
                        "65536 global values were found."));
}

}  // anonymous namespace
