// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// 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 "cobalt/browser/memory_tracker/tool/util.h"

#include <algorithm>
#include <iterator>
#include <string>
#include <vector>

#include "base/time/time.h"
#include "nb/bit_cast.h"
#include "starboard/common/string.h"

namespace cobalt {
namespace browser {
namespace memory_tracker {

const char kQuote[] = "\"";
const char kDelimiter[] = ",";
const char kNewLine[] = "\n";

std::string RemoveString(const std::string& haystack, const char* needle) {
  const size_t kNotFound = std::string::npos;

  // Base case. No modification needed.
  size_t pos = haystack.find(needle);
  if (pos == kNotFound) {
    return haystack;
  }
  const size_t n = strlen(needle);
  std::string output;
  output.reserve(haystack.size());

  // Copy string, omitting the portion containing the "needle".
  std::copy(haystack.begin(), haystack.begin() + pos,
            std::back_inserter(output));
  std::copy(haystack.begin() + pos + n, haystack.end(),
            std::back_inserter(output));

  // Recursively remove same needle in haystack.
  return RemoveString(output, needle);
}

std::string SanitizeCSVKey(std::string key) {
  key = RemoveString(key, kQuote);
  key = RemoveString(key, kDelimiter);
  key = RemoveString(key, kNewLine);
  return key;
}

std::string InsertCommasIntoNumberString(const std::string& input) {
  typedef std::vector<char> CharVector;
  typedef CharVector::iterator CharIt;

  CharVector chars(input.begin(), input.end());
  std::reverse(chars.begin(), chars.end());

  CharIt curr_it = chars.begin();
  CharIt mid = std::find(chars.begin(), chars.end(), '.');
  if (mid == chars.end()) {
    mid = curr_it;
  }

  CharVector out(curr_it, mid);

  int counter = 0;
  for (CharIt it = mid; it != chars.end(); ++it) {
    if (counter != 0 && (counter % 3 == 0)) {
      out.push_back(',');
    }
    if (*it != '.') {
      counter++;
    }
    out.push_back(*it);
  }

  std::reverse(out.begin(), out.end());
  std::stringstream ss;
  for (size_t i = 0; i < out.size(); ++i) {
    ss << out[i];
  }
  return ss.str();
}

Timer::Timer(base::TimeDelta delta_time) {
  start_time_ = Now();
  time_before_expiration_ = delta_time;
}

Timer::Timer(base::TimeDelta delta_time, Timer::TimeFunctor time_functor) {
  time_function_override_ = time_functor;
  start_time_ = Now();
  time_before_expiration_ = delta_time;
}

void Timer::Restart() { start_time_ = Now(); }

bool Timer::UpdateAndIsExpired() {
  base::TimeTicks now_time = Now();
  base::TimeDelta delta_time = now_time - start_time_;
  if (delta_time >= time_before_expiration_) {
    start_time_ = now_time;
    return true;
  } else {
    return false;
  }
}

base::TimeTicks Timer::Now() {
  if (time_function_override_.is_null()) {
    return base::TimeTicks::Now();
  } else {
    return time_function_override_.Run();
  }
}

void Timer::ScaleTriggerTime(double scale) {
  int64_t old_dt = time_before_expiration_.InMicroseconds();
  int64_t new_dt = static_cast<int64_t>(static_cast<double>(old_dt) * scale);
  time_before_expiration_ = base::TimeDelta::FromMicroseconds(new_dt);
}

Segment::Segment(const std::string* name, const char* start_address,
                 const char* end_address)
    : name_(name), begin_(start_address), end_(end_address) {}

void Segment::SplitAcrossPageBoundaries(size_t page_size,
                                        std::vector<Segment>* segments) const {
  if (size() == 0) {
    segments->push_back(*this);
    return;
  }

  uintptr_t page_start = nb::bit_cast<uintptr_t>(begin_) / page_size;
  uintptr_t page_end = nb::bit_cast<uintptr_t>(end_ - 1) / page_size;

  if (page_start == page_end) {
    segments->push_back(*this);
    return;
  }

  for (uintptr_t p = page_start; p <= page_end; ++p) {
    uintptr_t start_addr;
    if (p == page_start) {
      start_addr = nb::bit_cast<uintptr_t>(begin_);
    } else {
      start_addr = p * page_size;
    }

    uintptr_t end_addr;
    if (p == page_end) {
      end_addr = nb::bit_cast<uintptr_t>(end_);
    } else {
      end_addr = (p + 1) * page_size;
    }

    const char* start = nb::bit_cast<const char*>(start_addr);
    const char* end = nb::bit_cast<const char*>(end_addr);
    segments->push_back(Segment(name_, start, end));
  }
}

bool Segment::Intersects(const Segment& other) const {
  size_t total_span = std::distance(std::min(begin_, other.begin()),
                                    std::max(end_, other.end()));

  bool intersects = (size() + other.size()) > total_span;
  return intersects;
}

bool Segment::operator<(const Segment& other) const {
  return begin_ < other.begin();
}

bool Segment::operator==(const Segment& other) const {
  if (begin_ == other.begin() && end_ == other.end()) {
    DCHECK(name_ == other.name_);
    return true;
  }
  return false;
}

size_t Segment::size() const { return std::distance(begin_, end_); }

const char* BaseNameFast(const char* file_name) {
  // Case: Linux.
  const char* end_pos = file_name + strlen(file_name);
  const char* last_forward_slash = strrchr(file_name, '/');
  if (last_forward_slash) {
    if (end_pos != last_forward_slash) {
      ++last_forward_slash;
    }
    return last_forward_slash;
  }

  // Case: Windows.
  const char* last_backward_slash = strrchr(file_name, '\\');
  if (last_backward_slash) {
    if (end_pos != last_backward_slash) {
      ++last_backward_slash;
    }
    return last_backward_slash;
  }
  return file_name;
}

}  // namespace memory_tracker
}  // namespace browser
}  // namespace cobalt
