/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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_TRACED_PROBES_FILESYSTEM_PREFIX_FINDER_H_
#define SRC_TRACED_PROBES_FILESYSTEM_PREFIX_FINDER_H_

#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "perfetto/base/logging.h"

namespace perfetto {

// PrefixFinder allows to find prefixes for filenames that ensure that
// they can be found again within a provided limit of steps when searching
// within that prefix in the same order.
//
// For instance, let the limit be 4 and the filesystem be.
// /a/1
// /a/2
// /a/3
// /b/4
// /b/5
//
// The prefix for /a/1, /a/2 and /a/3/ is /, the one for /b/4 and /b/5 is /b/.
class PrefixFinder {
 public:
  // Opaque placeholder for a prefix that can be turned into a string
  // using ToString.
  // Can not be constructed outside of PrefixFinder.
  class Node {
   public:
    friend class PrefixFinder;
    Node(std::string name) : Node(std::move(name), nullptr) {}
    Node(std::string name, Node* parent)
        : name_(std::move(name)), parent_(parent) {}

    Node(const Node& that) = delete;
    Node& operator=(const Node&) = delete;

    // Return string representation of prefix, e.g. /foo/bar.
    // Does not include a trailing /.
    std::string ToString() const;

   private:
    // Add a new child to this node.
    Node* AddChild(std::string name);

    // Get existing child for this node. Return nullptr if it
    // does not exist.
    Node* MaybeChild(const std::string& name);

    const std::string name_;
    const Node* parent_;
    class NodeComparator {
     public:
      bool operator()(const Node& one, const Node& other) const {
        return one.name_ < other.name_;
      }
    };

    std::set<Node, NodeComparator> children_;
  };

  explicit PrefixFinder(size_t limit);

  // Add path to prefix mapping.
  // Must be called in DFS order.
  // Must be called before GetPrefix(path) for the same path.
  // Must not be called after Finalize.
  void AddPath(std::string path);

  // Return identifier for prefix. Ownership remains with the PrefixFinder.
  // Must be called after AddPath(path) for the same path.
  // Must not be before after Finalize.
  Node* GetPrefix(std::string path);

  // Call this after the last AddPath and before the first GetPrefix.
  void Finalize();

 private:
  // We're about to remove the suffix of state from i onwards,
  // if necessary add a prefix for anything in that suffix.
  void Flush(size_t i);
  void InsertPrefix(size_t len);
  const size_t limit_;
  // (path element, count) tuples for last path seen.
  std::vector<std::pair<std::string, size_t>> state_{{"", 0}};
  Node root_{"", nullptr};
#if PERFETTO_DCHECK_IS_ON()
  bool finalized_ = false;
#endif
};

}  // namespace perfetto
#endif  // SRC_TRACED_PROBES_FILESYSTEM_PREFIX_FINDER_H_
