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

#include "src/traced/probes/filesystem/prefix_finder.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_splitter.h"

namespace perfetto {

std::string PrefixFinder::Node::ToString() const {
  if (parent_ != nullptr)
    return parent_->ToString() + "/" + name_;
  return name_;
}

PrefixFinder::Node* PrefixFinder::Node::AddChild(std::string name) {
  auto it = children_.emplace(std::move(name), this);
  return const_cast<Node*>(&(*it.first));
}

PrefixFinder::Node* PrefixFinder::Node::MaybeChild(const std::string& name) {
  // This will be nicer with C++14 transparent comparators.
  // Then we will be able to look up by just the key using a sutiable
  // comparator.
  //
  // For now we need to allow to construct Node from the key.
  Node node(name);
  auto it = children_.find(node);
  if (it == children_.end())
    return nullptr;
  return const_cast<Node*>(&(*it));
}

PrefixFinder::PrefixFinder(size_t limit) : limit_(limit) {}

void PrefixFinder::InsertPrefix(size_t len) {
  Node* cur = &root_;
  for (auto it = state_.cbegin() + 1;
       it != state_.cbegin() + static_cast<ssize_t>(len + 1); it++) {
    Node* next = cur->MaybeChild(it->first);
    if (!next)
      next = cur->AddChild(it->first);
    cur = next;
  }
}

void PrefixFinder::Flush(size_t i) {
  PERFETTO_CHECK(i > 0);
  for (size_t j = i; j < state_.size(); ++j) {
    if (state_[j - 1].second > limit_ && state_[j].second <= limit_) {
      InsertPrefix(i);
      break;
    }
  }
}

void PrefixFinder::Finalize() {
  Flush(1);
  state_.resize(1);
#if PERFETTO_DCHECK_IS_ON()
  PERFETTO_DCHECK(!finalized_);
  finalized_ = true;
#endif
}

void PrefixFinder::AddPath(std::string path) {
  perfetto::base::StringSplitter s(std::move(path), '/');
  // An artificial element for the root directory.
  // This simplifies the logic below because we can always assume
  // there is a parent element.
  state_[0].second++;
  for (size_t i = 1; s.Next(); ++i) {
    char* token = s.cur_token();
    if (i < state_.size()) {
      std::pair<std::string, size_t>& elem = state_[i];
      if (elem.first == token) {
        elem.second++;
      } else {
        // Check if we need to write a prefix for any element
        // in the previous state.
        Flush(i);
        elem.first = token;
        elem.second = 1;
        state_.resize(i + 1);
      }
    } else {
      state_.emplace_back(token, 1);
    }
  }
}

PrefixFinder::Node* PrefixFinder::GetPrefix(std::string path) {
#if PERFETTO_DCHECK_IS_ON()
  PERFETTO_DCHECK(finalized_);
#endif
  perfetto::base::StringSplitter s(std::move(path), '/');
  Node* cur = &root_;
  for (size_t i = 0; s.Next(); ++i) {
    char* token = s.cur_token();
    Node* next = cur->MaybeChild(token);
    if (next == nullptr)
      break;
    cur = next;
    PERFETTO_DCHECK(cur->name_ == token);
  }
  return cur;
}

}  // namespace perfetto
