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

#include "agent.h"
#include "java_vm_ext.h"
#include "runtime.h"

namespace art {
namespace ti {

const char* AGENT_ON_LOAD_FUNCTION_NAME = "Agent_OnLoad";
const char* AGENT_ON_ATTACH_FUNCTION_NAME = "Agent_OnAttach";
const char* AGENT_ON_UNLOAD_FUNCTION_NAME = "Agent_OnUnload";

// TODO We need to acquire some locks probably.
Agent::LoadError Agent::DoLoadHelper(bool attaching,
                                     /*out*/jint* call_res,
                                     /*out*/std::string* error_msg) {
  DCHECK(call_res != nullptr);
  DCHECK(error_msg != nullptr);

  if (IsStarted()) {
    *error_msg = StringPrintf("the agent at %s has already been started!", name_.c_str());
    VLOG(agents) << "err: " << *error_msg;
    return kAlreadyStarted;
  }
  LoadError err = DoDlOpen(error_msg);
  if (err != kNoError) {
    VLOG(agents) << "err: " << *error_msg;
    return err;
  }
  AgentOnLoadFunction callback = attaching ? onattach_ : onload_;
  if (callback == nullptr) {
    *error_msg = StringPrintf("Unable to start agent %s: No %s callback found",
                              (attaching ? "attach" : "load"),
                              name_.c_str());
    VLOG(agents) << "err: " << *error_msg;
    return kLoadingError;
  }
  // Need to let the function fiddle with the array.
  std::unique_ptr<char[]> copied_args(new char[args_.size() + 1]);
  strcpy(copied_args.get(), args_.c_str());
  // TODO Need to do some checks that we are at a good spot etc.
  *call_res = callback(Runtime::Current()->GetJavaVM(),
                       copied_args.get(),
                       nullptr);
  if (*call_res != 0) {
    *error_msg = StringPrintf("Initialization of %s returned non-zero value of %d",
                              name_.c_str(), *call_res);
    VLOG(agents) << "err: " << *error_msg;
    return kInitializationError;
  } else {
    return kNoError;
  }
}

Agent::LoadError Agent::DoDlOpen(/*out*/std::string* error_msg) {
  DCHECK(error_msg != nullptr);

  DCHECK(dlopen_handle_ == nullptr);
  DCHECK(onload_ == nullptr);
  DCHECK(onattach_ == nullptr);
  DCHECK(onunload_ == nullptr);

  dlopen_handle_ = dlopen(name_.c_str(), RTLD_LAZY);
  if (dlopen_handle_ == nullptr) {
    *error_msg = StringPrintf("Unable to dlopen %s: %s", name_.c_str(), dlerror());
    return kLoadingError;
  }

  onload_ = reinterpret_cast<AgentOnLoadFunction>(dlsym(dlopen_handle_,
                                                        AGENT_ON_LOAD_FUNCTION_NAME));
  if (onload_ == nullptr) {
    VLOG(agents) << "Unable to find 'Agent_OnLoad' symbol in " << this;
  }
  onattach_ = reinterpret_cast<AgentOnLoadFunction>(dlsym(dlopen_handle_,
                                                            AGENT_ON_ATTACH_FUNCTION_NAME));
  if (onattach_ == nullptr) {
    VLOG(agents) << "Unable to find 'Agent_OnAttach' symbol in " << this;
  }
  onunload_= reinterpret_cast<AgentOnUnloadFunction>(dlsym(dlopen_handle_,
                                                           AGENT_ON_UNLOAD_FUNCTION_NAME));
  if (onunload_ == nullptr) {
    VLOG(agents) << "Unable to find 'Agent_OnUnload' symbol in " << this;
  }
  return kNoError;
}

// TODO Lock some stuff probably.
void Agent::Unload() {
  if (dlopen_handle_ != nullptr) {
    if (onunload_ != nullptr) {
      onunload_(Runtime::Current()->GetJavaVM());
    }
    dlclose(dlopen_handle_);
    dlopen_handle_ = nullptr;
    onload_ = nullptr;
    onattach_ = nullptr;
    onunload_ = nullptr;
  } else {
    VLOG(agents) << this << " is not currently loaded!";
  }
}

Agent::Agent(std::string arg)
    : dlopen_handle_(nullptr),
      onload_(nullptr),
      onattach_(nullptr),
      onunload_(nullptr) {
  size_t eq = arg.find_first_of('=');
  if (eq == std::string::npos) {
    name_ = arg;
  } else {
    name_ = arg.substr(0, eq);
    args_ = arg.substr(eq + 1, arg.length());
  }
}

Agent::Agent(const Agent& other)
    : dlopen_handle_(nullptr),
      onload_(nullptr),
      onattach_(nullptr),
      onunload_(nullptr) {
  *this = other;
}

// Attempting to copy to/from loaded/started agents is a fatal error
Agent& Agent::operator=(const Agent& other) {
  if (this != &other) {
    if (other.dlopen_handle_ != nullptr) {
      LOG(FATAL) << "Attempting to copy a loaded agent!";
    }

    if (dlopen_handle_ != nullptr) {
      LOG(FATAL) << "Attempting to assign into a loaded agent!";
    }

    DCHECK(other.onload_ == nullptr);
    DCHECK(other.onattach_ == nullptr);
    DCHECK(other.onunload_ == nullptr);

    DCHECK(onload_ == nullptr);
    DCHECK(onattach_ == nullptr);
    DCHECK(onunload_ == nullptr);

    name_ = other.name_;
    args_ = other.args_;

    dlopen_handle_ = nullptr;
    onload_ = nullptr;
    onattach_ = nullptr;
    onunload_ = nullptr;
  }
  return *this;
}

Agent::Agent(Agent&& other)
    : dlopen_handle_(nullptr),
      onload_(nullptr),
      onattach_(nullptr),
      onunload_(nullptr) {
  *this = std::move(other);
}

Agent& Agent::operator=(Agent&& other) {
  if (this != &other) {
    if (dlopen_handle_ != nullptr) {
      dlclose(dlopen_handle_);
    }
    name_ = std::move(other.name_);
    args_ = std::move(other.args_);
    dlopen_handle_ = other.dlopen_handle_;
    onload_ = other.onload_;
    onattach_ = other.onattach_;
    onunload_ = other.onunload_;
    other.dlopen_handle_ = nullptr;
    other.onload_ = nullptr;
    other.onattach_ = nullptr;
    other.onunload_ = nullptr;
  }
  return *this;
}

Agent::~Agent() {
  if (dlopen_handle_ != nullptr) {
    dlclose(dlopen_handle_);
  }
}

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

std::ostream& operator<<(std::ostream &os, Agent const& m) {
  return os << "Agent { name=\"" << m.name_ << "\", args=\"" << m.args_ << "\", handle="
            << m.dlopen_handle_ << " }";
}

}  // namespace ti
}  // namespace art
