// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_DIAGNOSTICS_CODE_TRACER_H_
#define V8_DIAGNOSTICS_CODE_TRACER_H_

#include "src/base/optional.h"
#include "src/base/platform/wrappers.h"
#include "src/common/globals.h"
#include "src/flags/flags.h"
#include "src/utils/allocation.h"
#include "src/utils/ostreams.h"
#include "src/utils/utils.h"
#include "src/utils/vector.h"

namespace v8 {
namespace internal {

class CodeTracer final : public Malloced {
 public:
#if defined(V8_OS_STARBOARD)
  explicit CodeTracer(int isolate_id) : scope_depth_(0) {
#else
  explicit CodeTracer(int isolate_id) : file_(nullptr), scope_depth_(0) {
    if (!ShouldRedirect()) {
      file_ = stdout;
      return;
    }
#endif

    if (FLAG_redirect_code_traces_to != nullptr) {
      StrNCpy(filename_, FLAG_redirect_code_traces_to, filename_.length());
    } else if (isolate_id >= 0) {
      SNPrintF(filename_, "code-%d-%d.asm", base::OS::GetCurrentProcessId(),
               isolate_id);
    } else {
      SNPrintF(filename_, "code-%d.asm", base::OS::GetCurrentProcessId());
    }

    WriteChars(filename_.begin(), "", 0, false);
  }

  class Scope {
   public:
    explicit Scope(CodeTracer* tracer) : tracer_(tracer) { tracer->OpenFile(); }
    ~Scope() { tracer_->CloseFile(); }

    FILE* file() const { return tracer_->file(); }

   private:
    CodeTracer* tracer_;
  };

  class StreamScope : public Scope {
   public:
    explicit StreamScope(CodeTracer* tracer) : Scope(tracer) {
      FILE* file = this->file();
      if (file == stdout) {
        stdout_stream_.emplace();
      } else {
        file_stream_.emplace(file);
      }
    }

    std::ostream& stream() {
      if (stdout_stream_.has_value()) return stdout_stream_.value();
      return file_stream_.value();
    }

   private:
    // Exactly one of these two will be initialized.
    base::Optional<StdoutStream> stdout_stream_;
    base::Optional<OFStream> file_stream_;
  };

  void OpenFile() {
    if (!ShouldRedirect()) {
      return;
    }

#if !defined(V8_OS_STARBOARD)
    if (file_ == nullptr) {
      file_ = base::OS::FOpen(filename_.begin(), "ab");
      CHECK_WITH_MSG(file_ != nullptr,
                     "could not open file. If on Android, try passing "
                     "--redirect-code-traces-to=/sdcard/Download/<file-name>");
    }
#endif

    scope_depth_++;
  }

  void CloseFile() {
    if (!ShouldRedirect()) {
      return;
    }

    if (--scope_depth_ == 0) {
#if !defined(V8_OS_STARBOARD)
      DCHECK_NOT_NULL(file_);
      base::Fclose(file_);
      file_ = nullptr;
#endif
    }
  }

#if !defined(V8_OS_STARBOARD)
  FILE* file() const { return file_; }
#else
  FILE* file() const { return nullptr; }
#endif

 private:
  static bool ShouldRedirect() { return FLAG_redirect_code_traces; }

  EmbeddedVector<char, 128> filename_;
#if !defined(V8_OS_STARBOARD)
  FILE* file_;
#endif
  int scope_depth_;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_DIAGNOSTICS_CODE_TRACER_H_
