text: // Copyright 2017 The Fuchsia Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
  
  #include <src/lib/fxl/strings/join_strings.h>
  
  #include <string>
  #include <vector>
  
  #include "peridot/lib/util/string_escape.h"
  
  namespace modular {
  
  std::string MakeDeviceKey(const fidl::StringPtr& device_name) {
    // Not escaped, because only one component after the prefix.
    return kDeviceKeyPrefix + device_name.get();
  }
  
  std::string MakeFocusKey(const fidl::StringPtr& device_name) {
    // Not escaped, because only one component after the prefix.
    return kFocusKeyPrefix + device_name.get();
  }
  
  std::string MakeMessageQueuesPrefix(const std::string& component_namespace) {
    std::string key{kMessageQueueTokenKeyPrefix};
    key.append(StringEscape(component_namespace, kSeparator, kEscaper));
    key.append(kSeparator);
    return key;
  }
  
  std::string MakeMessageQueueTokenKey(const std::string& component_namespace,
                                       const std::string& component_instance_id,
                                       const std::string& queue_name) {
    std::string key{kMessageQueueTokenKeyPrefix};
    key.append(StringEscape(component_namespace, kSeparator, kEscaper));
    key.append(kSeparator);
    key.append(StringEscape(component_instance_id, kSeparator, kEscaper));
    key.append(kSeparator);
    key.append(StringEscape(queue_name, kSeparator, kEscaper));
    return key;
  }
  
  std::string MakeMessageQueueKey(const std::string& queue_token) {
    // Not escaped, because only one component after the prefix.
    return kMessageQueueKeyPrefix + queue_token;
  }
  
  std::string EncodeModulePath(const std::vector<std::string>& module_path) {
    std::vector<std::string> segments;
    segments.reserve(module_path.size());
    for (const auto& module_path_part : module_path) {
      segments.emplace_back(StringEscape(module_path_part, kCharsToEscape, kEscaper));
    }
    return fxl::JoinStrings(segments, kSubSeparator);
  }
  
  std::string EncodeLinkPath(const fuchsia::modular::LinkPath& link_path) {
    std::string output;
    output.append(EncodeModulePath(link_path.module_path));
    output.append(kSeparator);
    output.append(StringEscape(link_path.link_name.get(), kCharsToEscape, kEscaper));
    return output;
  }
  
  std::string EncodeModuleComponentNamespace(const std::string& story_id) {
    // TODO(mesch): Needs escaping, and must not be escaped when used as component
    // of a full key. Messy.
    return "story:" + story_id;
  }
  
  std::string MakeTriggerKey(const std::string& agent_url, const std::string& task_id) {
    std::string key{kTriggerKeyPrefix};
    key.append(StringEscape(agent_url, kCharsToEscape, kEscaper));
    key.append(kSeparator);
    key.append(StringEscape(task_id, kCharsToEscape, kEscaper));
    return key;
  }
  
  std::string MakeLinkKey(const fuchsia::modular::LinkPathPtr& link_path) {
    return MakeLinkKey(*link_path);
  }
  
  std::string MakeLinkKey(const fuchsia::modular::LinkPath& link_path) {
    std::string key{kLinkKeyPrefix};
    key.append(EncodeLinkPath(link_path));
    return key;
  }
  
  std::string MakeModuleKey(const std::vector<std::string>& module_path) {
    FXL_DCHECK(module_path.size() > 0) << EncodeModulePath(module_path);
    FXL_DCHECK(module_path.at(0).size() > 0) << EncodeModulePath(module_path);
    std::string key{kModuleKeyPrefix};
    key.append(EncodeModulePath(module_path));
    return key;
  }
  
  }  // namespace modular
  