/*
 * Copyright (C) 2019 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_TRACE_PROCESSOR_SYSTRACE_UTILS_H_
#define SRC_TRACE_PROCESSOR_SYSTRACE_UTILS_H_

#include <string>

#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_view.h"

namespace perfetto {
namespace trace_processor {
namespace systrace_utils {

struct SystraceTracePoint {
  SystraceTracePoint() {}

  SystraceTracePoint(char p, uint32_t tg, base::StringView n, double v)
      : phase(p), tgid(tg), name(std::move(n)), value(v) {}

  // Phase can be one of B, E or C.
  char phase = '\0';

  uint32_t tgid = 0;

  // For phase = 'B' and phase = 'C' only.
  base::StringView name;

  // For phase = 'C' only.
  double value = 0;
};

inline bool operator==(const SystraceTracePoint& x,
                       const SystraceTracePoint& y) {
  return std::tie(x.phase, x.tgid, x.name, x.value) ==
         std::tie(y.phase, y.tgid, y.name, y.value);
}

enum class SystraceParseResult { kFailure = 0, kUnsupported, kSuccess };

// We have to handle trace_marker events of a few different types:
// 1. some random text
// 2. B|1636|pokeUserActivity
// 3. E|1636
// 4. C|1636|wq:monitor|0
inline SystraceParseResult ParseSystraceTracePoint(base::StringView str,
                                                   SystraceTracePoint* out) {
  const char* s = str.data();
  size_t len = str.size();

  if (len < 2)
    return SystraceParseResult::kFailure;

  // If str matches '[BEC]\|[0-9]+[\|\n]' set tgid_length to the length of
  // the number. Otherwise return kFailure.
  if (s[1] != '|' && s[1] != '\n')
    return SystraceParseResult::kFailure;
  if (s[0] != 'B' && s[0] != 'E' && s[0] != 'C') {
    // TODO: support android async slices
    return s[0] == 'S' || s[0] == 'F' ? SystraceParseResult::kUnsupported
                                      : SystraceParseResult::kFailure;
  }
  size_t tgid_length = 0;
  for (size_t i = 2; i < len; i++) {
    if (s[i] == '|' || s[i] == '\n') {
      tgid_length = i - 2;
      break;
    }
    if (s[i] < '0' || s[i] > '9')
      return SystraceParseResult::kFailure;
  }

  if (tgid_length == 0) {
    out->tgid = 0;
  } else {
    std::string tgid_str(s + 2, tgid_length);
    out->tgid = static_cast<uint32_t>(std::stoi(tgid_str.c_str()));
  }

  out->phase = s[0];
  switch (s[0]) {
    case 'B': {
      size_t name_index = 2 + tgid_length + 1;
      out->name = base::StringView(
          s + name_index, len - name_index - (s[len - 1] == '\n' ? 1 : 0));
      return SystraceParseResult::kSuccess;
    }
    case 'E': {
      return SystraceParseResult::kSuccess;
    }
    case 'C': {
      size_t name_index = 2 + tgid_length + 1;
      base::Optional<size_t> name_length;
      for (size_t i = name_index; i < len; i++) {
        if (s[i] == '|') {
          name_length = i - name_index;
          break;
        }
      }
      if (!name_length.has_value())
        return SystraceParseResult::kFailure;
      out->name = base::StringView(s + name_index, name_length.value());

      size_t value_index = name_index + name_length.value() + 1;
      size_t value_len = len - value_index;
      if (value_len == 0)
        return SystraceParseResult::kFailure;
      std::string value_str(s + value_index, value_len);
      out->value = std::stod(value_str.c_str());
      return SystraceParseResult::kSuccess;
    }
    default:
      return SystraceParseResult::kFailure;
  }
}

}  // namespace systrace_utils
}  // namespace trace_processor
}  // namespace perfetto

#endif  // SRC_TRACE_PROCESSOR_SYSTRACE_UTILS_H_
