// Copyright 2020 The Tint 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.

#ifndef SRC_READER_SPIRV_NAMER_H_
#define SRC_READER_SPIRV_NAMER_H_

#include <string>
#include <unordered_map>
#include <vector>

#include "src/reader/spirv/fail_stream.h"

namespace tint {
namespace reader {
namespace spirv {

/// A Namer maps SPIR-V IDs to strings.
///
/// Sanitization:
/// Some names are user-suggested, but "sanitized" in the sense that an
/// unusual character (e.g. invalid for use in WGSL identifiers) is remapped
/// to a safer character such as an underscore.  Also, sanitized names
/// never start with an underscore.
class Namer {
 public:
  /// Creates a new namer
  /// @param fail_stream the error reporting stream
  explicit Namer(const FailStream& fail_stream);
  /// Destructor
  ~Namer();

  /// Sanitizes the given string, to replace unusual characters with
  /// obviously-valid idenfier characters. An empy string yields "empty".
  /// A sanitized name never starts with an underscore.
  /// @param suggested_name input string
  /// @returns sanitized name, suitable for use as an identifier
  static std::string Sanitize(const std::string& suggested_name);

  /// Registers a failure.
  /// @returns a fail stream to accumulate diagnostics.
  FailStream& Fail() { return fail_stream_.Fail(); }

  /// @param id the SPIR-V ID
  /// @returns true if we the given ID already has a registered name.
  bool HasName(uint32_t id) {
    return id_to_name_.find(id) != id_to_name_.end();
  }

  /// @param name a string
  /// @returns true if the string has been registered as a name.
  bool IsRegistered(const std::string& name) const {
    return name_to_id_.find(name) != name_to_id_.end();
  }

  /// @param id the SPIR-V ID
  /// @returns the name for the ID. It must have been registered.
  const std::string& GetName(uint32_t id) const {
    return id_to_name_.find(id)->second;
  }

  /// Gets a unique name for the ID. If one already exists, then return
  /// that, otherwise synthesize a name and remember it for later.
  /// @param id the SPIR-V ID
  /// @returns a name for the given ID. Generates a name if non exists.
  const std::string& Name(uint32_t id) {
    if (!HasName(id)) {
      SuggestSanitizedName(id, "x_" + std::to_string(id));
    }
    return GetName(id);
  }

  /// Gets the registered name for a struct member. If no name has
  /// been registered for this member, then returns the empty string.
  /// member index is in bounds.
  /// @param id the SPIR-V ID of the struct type
  /// @param member_index the index of the member, counting from 0
  /// @returns the registered name for the ID, or an empty string if
  /// nothing has been registered.
  std::string GetMemberName(uint32_t id, uint32_t member_index) const;

  /// Returns an unregistered name based on a given base name.
  /// @param base_name the base name
  /// @returns a new name
  std::string FindUnusedDerivedName(const std::string& base_name) const;

  /// Returns a newly registered name based on a given base name.
  /// In the internal table `name_to_id_`, it is mapped to the invalid
  /// SPIR-V ID 0.  It does not have an entry in `id_to_name_`.
  /// @param base_name the base name
  /// @returns a new name
  std::string MakeDerivedName(const std::string& base_name);

  /// Records a mapping from the given ID to a name. Emits a failure
  /// if the ID already has a registered name.
  /// @param id the SPIR-V ID
  /// @param name the name to map to the ID
  /// @returns true if the ID did not have a previously registered name.
  bool Register(uint32_t id, const std::string& name);

  /// Registers a name, but not associated to any ID. Fails and emits
  /// a diagnostic if the name was already registered.
  /// @param name the name to register
  /// @returns true if the name was not already reegistered.
  bool RegisterWithoutId(const std::string& name);

  /// Saves a sanitized name for the given ID, if that ID does not yet
  /// have a registered name, and if the sanitized name has not already
  /// been registered to a different ID.
  /// @param id the SPIR-V ID
  /// @param suggested_name the suggested name
  /// @returns true if a name was newly registered for the ID
  bool SuggestSanitizedName(uint32_t id, const std::string& suggested_name);

  /// Saves a sanitized name for a member of a struct, if that member
  /// does not yet have a registered name.
  /// @param struct_id the SPIR-V ID for the struct
  /// @param member_index the index of the member inside the struct
  /// @param suggested_name the suggested name
  /// @returns true if a name was newly registered
  bool SuggestSanitizedMemberName(uint32_t struct_id,
                                  uint32_t member_index,
                                  const std::string& suggested_name);

  /// Ensure there are member names registered for members of the given struct
  /// such that:
  /// - Each member has a non-empty sanitized name.
  /// - No two members in the struct have the same name.
  /// @param struct_id the SPIR-V ID for the struct
  /// @param num_members the number of members in the struct
  void ResolveMemberNamesForStruct(uint32_t struct_id, uint32_t num_members);

 private:
  FailStream fail_stream_;

  // Maps an ID to its registered name.
  std::unordered_map<uint32_t, std::string> id_to_name_;
  // Maps a name to a SPIR-V ID, or 0 (the case for derived names).
  std::unordered_map<std::string, uint32_t> name_to_id_;

  // Maps a struct id and member index to a suggested sanitized name.
  // If entry k in the vector is an empty string, then a suggestion
  // was recorded for a higher-numbered index, but not for index k.
  std::unordered_map<uint32_t, std::vector<std::string>> struct_member_names_;
};

}  // namespace spirv
}  // namespace reader
}  // namespace tint

#endif  // SRC_READER_SPIRV_NAMER_H_
