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

#include "src/trace_processor/ftrace_utils.h"

#include <stdint.h>
#include <algorithm>

#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_writer.h"

namespace perfetto {
namespace trace_processor {
namespace ftrace_utils {

namespace {
struct FtraceTime {
  FtraceTime(int64_t ns)
      : secs(ns / 1000000000LL), micros((ns - secs * 1000000000LL) / 1000) {}

  const int64_t secs;
  const int64_t micros;
};
}  // namespace

TaskState::TaskState(uint16_t raw_state) {
  if (raw_state > kMaxState) {
    state_ = 0;
  } else {
    state_ = raw_state | kValid;
  }
}

TaskState::TaskState(const char* state_str) {
  bool invalid_char = false;
  bool is_runnable = false;
  for (size_t i = 0; state_str[i] != '\0'; i++) {
    char c = state_str[i];
    if (is_kernel_preempt()) {
      // No other character should be encountered after '+'.
      invalid_char = true;
      break;
    } else if (c == '+') {
      state_ |= kMaxState;
      continue;
    }

    if (is_runnable) {
      // We should not encounter any character apart from '+' if runnable.
      invalid_char = true;
      break;
    }

    if (c == 'R') {
      if (state_ != 0) {
        // We should not encounter R if we already have set other atoms.
        invalid_char = true;
        break;
      } else {
        is_runnable = true;
        continue;
      }
    }

    if (c == 'S')
      state_ |= Atom::kInterruptibleSleep;
    else if (c == 'D')
      state_ |= Atom::kUninterruptibleSleep;
    else if (c == 'T')
      state_ |= Atom::kStopped;
    else if (c == 't')
      state_ |= Atom::kTraced;
    else if (c == 'X')
      state_ |= Atom::kExitDead;
    else if (c == 'Z')
      state_ |= Atom::kExitZombie;
    else if (c == 'x')
      state_ |= Atom::kTaskDead;
    else if (c == 'K')
      state_ |= Atom::kWakeKill;
    else if (c == 'W')
      state_ |= Atom::kWaking;
    else if (c == 'P')
      state_ |= Atom::kParked;
    else if (c == 'N')
      state_ |= Atom::kNoLoad;
    else if (c == '|')
      continue;
    else {
      invalid_char = true;
      break;
    }
  }

  bool no_state = !is_runnable && state_ == 0;
  if (invalid_char || no_state || state_ > kMaxState) {
    state_ = 0;
  } else {
    state_ |= kValid;
  }
}

TaskState::TaskStateStr TaskState::ToString(char separator) const {
  PERFETTO_CHECK(is_valid());

  char buffer[32];
  size_t pos = 0;

  // This mapping is given by the file
  // https://android.googlesource.com/kernel/msm.git/+/android-msm-wahoo-4.4-pie-qpr1/include/trace/events/sched.h#155
  if (is_runnable()) {
    buffer[pos++] = 'R';
  } else {
    if (state_ & Atom::kInterruptibleSleep)
      buffer[pos++] = 'S';
    if (state_ & Atom::kUninterruptibleSleep) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'D';  // D for (D)isk sleep
    }
    if (state_ & Atom::kStopped) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'T';
    }
    if (state_ & Atom::kTraced) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 't';
    }
    if (state_ & Atom::kExitDead) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'X';
    }
    if (state_ & Atom::kExitZombie) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'Z';
    }
    if (state_ & Atom::kTaskDead) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'x';
    }
    if (state_ & Atom::kWakeKill) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'K';
    }
    if (state_ & Atom::kWaking) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'W';
    }
    if (state_ & Atom::kParked) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'P';
    }
    if (state_ & Atom::kNoLoad) {
      if (separator && pos != 0)
        buffer[pos++] = separator;
      buffer[pos++] = 'N';
    }
  }

  if (is_kernel_preempt())
    buffer[pos++] = '+';

  TaskStateStr output{};
  memcpy(output.data(), buffer, std::min(pos, output.size() - 1));
  return output;
}

void FormatSystracePrefix(int64_t timestamp,
                          uint32_t cpu,
                          uint32_t pid,
                          uint32_t tgid,
                          base::StringView name,
                          base::StringWriter* writer) {
  FtraceTime ftrace_time(timestamp);
  if (pid == 0) {
    name = "<idle>";
  } else if (name == "") {
    name = "<unknown>";
  } else if (name == "CrRendererMain") {
    // TODO(taylori): Remove this when crbug.com/978093 is fixed or
    // when a better solution is found.
    name = "CrRendererMainThread";
  }

  int64_t padding = 16 - static_cast<int64_t>(name.size());
  if (padding > 0) {
    writer->AppendChar(' ', static_cast<size_t>(padding));
  }
  for (size_t i = 0; i < name.size(); ++i) {
    char c = name.data()[i];
    writer->AppendChar(c == '-' ? '_' : c);
  }
  writer->AppendChar('-');

  size_t pre_pid_pos = writer->pos();
  writer->AppendInt(pid);
  size_t pid_chars = writer->pos() - pre_pid_pos;
  if (PERFETTO_LIKELY(pid_chars < 5)) {
    writer->AppendChar(' ', 5 - pid_chars);
  }

  writer->AppendLiteral(" (");
  if (tgid == 0) {
    writer->AppendLiteral("-----");
  } else {
    writer->AppendPaddedInt<' ', 5>(tgid);
  }
  writer->AppendLiteral(") [");
  writer->AppendPaddedInt<'0', 3>(cpu);
  writer->AppendLiteral("] .... ");

  writer->AppendInt(ftrace_time.secs);
  writer->AppendChar('.');
  writer->AppendPaddedInt<'0', 6>(ftrace_time.micros);
  writer->AppendChar(':');
}

}  // namespace ftrace_utils
}  // namespace trace_processor
}  // namespace perfetto
