/*
 * Copyright (C) 2015 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <pthread.h>
#include <stdint.h>
#include <stdlib.h>

#include <algorithm>
#include <vector>

#include <private/ScopedPthreadMutexLocker.h>

#include "backtrace.h"
#include "BacktraceData.h"
#include "Config.h"
#include "DebugData.h"
#include "debug_disable.h"
#include "debug_log.h"
#include "malloc_debug.h"
#include "TrackData.h"

TrackData::TrackData(DebugData* debug_data) : OptionData(debug_data) {
}

void TrackData::GetList(std::vector<const Header*>* list) {
  for (const auto& header : headers_) {
    list->push_back(header);
  }

  // Sort by the size of the allocation.
  std::sort(list->begin(), list->end(), [](const Header* a, const Header* b) {
    if (a->size == b->size) return a < b;
    return a->size > b->size;
  });
}

void TrackData::Add(const Header* header, bool backtrace_found) {
  pthread_mutex_lock(&mutex_);
  if (backtrace_found) {
    total_backtrace_allocs_++;
  }
  headers_.insert(header);
  pthread_mutex_unlock(&mutex_);
}

void TrackData::Remove(const Header* header, bool backtrace_found) {
  pthread_mutex_lock(&mutex_);
  headers_.erase(header);
  if (backtrace_found) {
    total_backtrace_allocs_--;
  }
  pthread_mutex_unlock(&mutex_);
}

bool TrackData::Contains(const Header* header) {
  pthread_mutex_lock(&mutex_);
  bool found = headers_.count(header);
  pthread_mutex_unlock(&mutex_);
  return found;
}

void TrackData::DisplayLeaks() {
  std::vector<const Header*> list;
  GetList(&list);

  size_t track_count = 0;
  for (const auto& header : list) {
    error_log("+++ %s leaked block of size %zu at %p (leak %zu of %zu)", getprogname(),
              header->real_size(), debug_->GetPointer(header), ++track_count, list.size());
    if (debug_->config().options & BACKTRACE) {
      BacktraceHeader* back_header = debug_->GetAllocBacktrace(header);
      if (back_header->num_frames > 0) {
        error_log("Backtrace at time of allocation:");
        backtrace_log(&back_header->frames[0], back_header->num_frames);
      }
    }
    g_dispatch->free(header->orig_pointer);
  }
}

void TrackData::GetInfo(uint8_t** info, size_t* overall_size, size_t* info_size,
                        size_t* total_memory, size_t* backtrace_size) {
  ScopedPthreadMutexLocker scoped(&mutex_);

  if (headers_.size() == 0 || total_backtrace_allocs_ == 0) {
    return;
  }

  *backtrace_size = debug_->config().backtrace_frames;
  *info_size = sizeof(size_t) * 2 + sizeof(uintptr_t) * *backtrace_size;
  *info = reinterpret_cast<uint8_t*>(g_dispatch->calloc(*info_size, total_backtrace_allocs_));
  if (*info == nullptr) {
    return;
  }
  *overall_size = *info_size * total_backtrace_allocs_;

  std::vector<const Header*> list;
  GetList(&list);

  uint8_t* data = *info;
  for (const auto& header : list) {
    BacktraceHeader* back_header = debug_->GetAllocBacktrace(header);
    if (back_header->num_frames > 0) {
      memcpy(data, &header->size, sizeof(size_t));
      memcpy(&data[sizeof(size_t)], &back_header->num_frames, sizeof(size_t));
      memcpy(&data[2 * sizeof(size_t)], &back_header->frames[0],
            back_header->num_frames * sizeof(uintptr_t));

      *total_memory += header->real_size();

      data += *info_size;
    }
  }
}
