/*
 * Copyright (C) 2016 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 ART_RUNTIME_TI_AGENT_H_
#define ART_RUNTIME_TI_AGENT_H_

#include <dlfcn.h>
#include <jni.h>  // for jint, JavaVM* etc declarations

#include "base/stringprintf.h"
#include "runtime.h"
#include "utils.h"

namespace art {
namespace ti {

using AgentOnLoadFunction = jint (*)(JavaVM*, const char*, void*);
using AgentOnUnloadFunction = void (*)(JavaVM*);

// TODO: consider splitting ti::Agent into command line, agent and shared library handler classes

class Agent {
 public:
  enum LoadError {
    kNoError,              // No error occurred..
    kAlreadyStarted,       // The agent has already been loaded.
    kLoadingError,         // dlopen or dlsym returned an error.
    kInitializationError,  // The entrypoint did not return 0. This might require an abort.
  };

  bool IsStarted() const {
    return dlopen_handle_ != nullptr;
  }

  const std::string& GetName() const {
    return name_;
  }

  const std::string& GetArgs() const {
    return args_;
  }

  bool HasArgs() const {
    return !GetArgs().empty();
  }

  LoadError Load(/*out*/jint* call_res, /*out*/std::string* error_msg) {
    VLOG(agents) << "Loading agent: " << name_ << " " << args_;
    return DoLoadHelper(false, call_res, error_msg);
  }

  // TODO We need to acquire some locks probably.
  void Unload();

  // Tries to attach the agent using its OnAttach method. Returns true on success.
  LoadError Attach(/*out*/jint* call_res, /*out*/std::string* error_msg) {
    VLOG(agents) << "Attaching agent: " << name_ << " " << args_;
    return DoLoadHelper(true, call_res, error_msg);
  }

  explicit Agent(std::string arg);

  Agent(const Agent& other);
  Agent& operator=(const Agent& other);

  Agent(Agent&& other);
  Agent& operator=(Agent&& other);

  ~Agent();

 private:
  LoadError DoDlOpen(/*out*/std::string* error_msg);

  LoadError DoLoadHelper(bool attaching,
                         /*out*/jint* call_res,
                         /*out*/std::string* error_msg);

  std::string name_;
  std::string args_;
  void* dlopen_handle_;

  // The entrypoints.
  AgentOnLoadFunction onload_;
  AgentOnLoadFunction onattach_;
  AgentOnUnloadFunction onunload_;

  friend std::ostream& operator<<(std::ostream &os, Agent const& m);
};

std::ostream& operator<<(std::ostream &os, Agent const& m);
std::ostream& operator<<(std::ostream &os, const Agent* m);

}  // namespace ti
}  // namespace art

#endif  // ART_RUNTIME_TI_AGENT_H_

