// 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.

#ifndef SPIRV_TOOLS_LINKER_HPP_
#define SPIRV_TOOLS_LINKER_HPP_

#include <cstdint>

#include <memory>
#include <vector>

#include "libspirv.hpp"

namespace spvtools {

class LinkerOptions {
 public:
  LinkerOptions()
      : create_library_(false),
        verify_ids_(false),
        allow_partial_linkage_(false) {}

  // Returns whether a library or an executable should be produced by the
  // linking phase.
  //
  // All exported symbols are kept when creating a library, whereas they will
  // be removed when creating an executable.
  // The returned value will be true if creating a library, and false if
  // creating an executable.
  bool GetCreateLibrary() const { return create_library_; }

  // Sets whether a library or an executable should be produced.
  void SetCreateLibrary(bool create_library) {
    create_library_ = create_library;
  }

  // Returns whether to verify the uniqueness of the unique ids in the merged
  // context.
  bool GetVerifyIds() const { return verify_ids_; }

  // Sets whether to verify the uniqueness of the unique ids in the merged
  // context.
  void SetVerifyIds(bool verify_ids) { verify_ids_ = verify_ids; }

  // Returns whether to allow for imported symbols to have no corresponding
  // exported symbols
  bool GetAllowPartialLinkage() const { return allow_partial_linkage_; }

  // Sets whether to allow for imported symbols to have no corresponding
  // exported symbols
  void SetAllowPartialLinkage(bool allow_partial_linkage) {
    allow_partial_linkage_ = allow_partial_linkage;
  }

 private:
  bool create_library_;
  bool verify_ids_;
  bool allow_partial_linkage_;
};

// Links one or more SPIR-V modules into a new SPIR-V module. That is, combine
// several SPIR-V modules into one, resolving link dependencies between them.
//
// At least one binary has to be provided in |binaries|. Those binaries do not
// have to be valid, but they should be at least parseable.
// The functions can fail due to the following:
// * The given context was not initialised using `spvContextCreate()`;
// * No input modules were given;
// * One or more of those modules were not parseable;
// * The input modules used different addressing or memory models;
// * The ID or global variable number limit were exceeded;
// * Some entry points were defined multiple times;
// * Some imported symbols did not have an exported counterpart;
// * Possibly other reasons.
spv_result_t Link(const Context& context,
                  const std::vector<std::vector<uint32_t>>& binaries,
                  std::vector<uint32_t>* linked_binary,
                  const LinkerOptions& options = LinkerOptions());
spv_result_t Link(const Context& context, const uint32_t* const* binaries,
                  const size_t* binary_sizes, size_t num_binaries,
                  std::vector<uint32_t>* linked_binary,
                  const LinkerOptions& options = LinkerOptions());

}  // namespace spvtools

#endif  // SPIRV_TOOLS_LINKER_HPP_
