// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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 "syzygy/grinder/line_info.h"

#include <dia2.h>
#include <algorithm>
#include <limits>

#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "syzygy/common/com_utils.h"
#include "syzygy/core/address_space.h"

namespace grinder {

namespace {

using base::win::ScopedBstr;
using base::win::ScopedComPtr;

typedef core::AddressRange<core::RelativeAddress, size_t> RelativeAddressRange;
typedef std::map<DWORD, const std::string*> SourceFileMap;

bool GetDiaSessionForPdb(const base::FilePath& pdb_path,
                         IDiaDataSource* source,
                         IDiaSession** session) {
  DCHECK(source != NULL);
  DCHECK(session != NULL);

  HRESULT hr = source->loadDataFromPdb(pdb_path.value().c_str());
  if (FAILED(hr)) {
    LOG(ERROR) << "Failure in loadDataFromPdb: " << common::LogHr(hr) << ".";
    return false;
  }

  hr = source->openSession(session);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failure in openSession: " << common::LogHr(hr) << ".";
    return false;
  }

  return true;
}


bool DisableOmapTranslation(IDiaSession* session) {
  DCHECK(session != NULL);

  ScopedComPtr<IDiaAddressMap> addr_map;
  HRESULT hr = session->QueryInterface(IID_IDiaAddressMap,
                                       addr_map.ReceiveVoid());
  if (FAILED(hr)) {
    LOG(ERROR) << "Failure in QueryInterface: " << common::LogHr(hr) << ".";
    return false;
  }
  hr = addr_map->put_addressMapEnabled(FALSE);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failure in put_addressMapEnabled: " << common::LogHr(hr)
               << ".";
    return false;
  }

  return true;
}

const std::string* GetSourceFileName(DWORD source_file_id,
                                     IDiaLineNumber* line_number,
                                     LineInfo::SourceFileSet* source_files,
                                     SourceFileMap* source_file_map) {
  DCHECK(line_number != NULL);
  DCHECK(source_files != NULL);
  DCHECK(source_file_map != NULL);

  SourceFileMap::const_iterator map_it = source_file_map->find(source_file_id);

  if (map_it != source_file_map->end())
    return map_it->second;

  ScopedComPtr<IDiaSourceFile> source_file;
  HRESULT hr = line_number->get_sourceFile(source_file.Receive());
  if (FAILED(hr)) {
    LOG(ERROR) << "Failure in get_sourceFile: " << common::LogHr(hr) << ".";
    return NULL;
  }

  ScopedBstr source_file_path_bstr;
  hr = source_file->get_fileName(source_file_path_bstr.Receive());
  if (FAILED(hr)) {
    LOG(ERROR) << "Failure in get_fileName: " << common::LogHr(hr) << ".";
    return NULL;
  }

  std::string source_file_path;
  if (!base::WideToUTF8(common::ToString(source_file_path_bstr),
                        source_file_path_bstr.Length(),
                        &source_file_path)) {
    LOG(ERROR) << "base::WideToUTF8 failed for path \""
               << common::ToString(source_file_path_bstr) << "\".";
    return NULL;
  }

  LineInfo::SourceFileSet::const_iterator source_file_it =
      source_files->insert(source_file_path).first;
  const std::string* source_file_name = &(*source_file_it);
  source_file_map->insert(std::make_pair(source_file_id,
                                         source_file_name));

  return source_file_name;
}

// Used for comparing the ranges covered by two source lines.
struct SourceLineAddressComparator {
  bool operator()(const LineInfo::SourceLine& sl1,
                  const LineInfo::SourceLine& sl2) const {
    return sl1.address + sl1.size <= sl2.address;
  }
};

}  // namespace

bool LineInfo::Init(const base::FilePath& pdb_path) {
  ScopedComPtr<IDiaDataSource> source;
  HRESULT hr = source.CreateInstance(CLSID_DiaSource);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed to create DiaSource: " << common::LogHr(hr) << ".";
    return false;
  }

  ScopedComPtr<IDiaSession> session;
  if (!GetDiaSessionForPdb(pdb_path, source.get(), session.Receive()))
    return false;

  // We want original module addresses so we disable OMAP translation.
  if (!DisableOmapTranslation(session.get()))
    return false;

  // Get the line number enumeration.
  ScopedComPtr<IDiaEnumLineNumbers> line_number_enum;
  hr = session->findLinesByRVA(0, 0xFFFFFF, line_number_enum.Receive());
  if (FAILED(hr)) {
    LOG(ERROR) << "Failure in findLinesByRVA: " << common::LogHr(hr) << ".";
    return false;
  }

  // A map of source file IDs we've already seen, mapping back to the source
  // file path. We use this as a cache so we're not constantly doing source-file
  // lookups while iterating.
  SourceFileMap source_file_map;

  // Get the line info count and reserve space.
  LONG line_number_count = 0;
  hr = line_number_enum->get_Count(&line_number_count);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failure in get_Count: " << common::LogHr(hr) << ".";
    return false;
  }
  source_lines_.reserve(line_number_count);

  // Iterate over the source line information.
  DWORD old_source_file_id = -1;
  DWORD old_rva = 0;
  const std::string* source_file_name = NULL;
  while (true) {
    ScopedComPtr<IDiaLineNumber> line_number;
    ULONG fetched = 0;
    hr = line_number_enum->Next(1, line_number.Receive(), &fetched);
    if (hr != S_OK || fetched != 1)
      break;

    DWORD source_file_id = 0;
    hr = line_number->get_sourceFileId(&source_file_id);
    if (FAILED(hr)) {
      LOG(ERROR) << "Failure in get_sourceFileId: " << common::LogHr(hr) << ".";
      return false;
    }

    // Look for the source file by ID. Since we most often see successive
    // lines from the same file we have a shortcut to avoid extra processing in
    // this case.
    if (source_file_id != old_source_file_id) {
      source_file_name = GetSourceFileName(source_file_id,
                                           line_number.get(),
                                           &source_files_,
                                           &source_file_map);
    }
    old_source_file_id = source_file_id;
    DCHECK(source_file_name != NULL);

    DWORD line = 0;
    DWORD rva = 0;
    DWORD length = 0;
    if (FAILED(line_number->get_lineNumber(&line)) ||
        FAILED(line_number->get_relativeVirtualAddress(&rva)) ||
        FAILED(line_number->get_length(&length))) {
      LOG(ERROR) << "Failed to get line number properties.";
      return false;
    }

    // We rely on the enumeration returning us lines in order of increasing
    // address, as they are stored originally in the PDB. This is required for
    // the following zero-length fixing mechanism to work as intended.
    DCHECK_LE(old_rva, rva);
    old_rva = rva;

    // Is this a non-zero length? Back up and make any zero-length ranges
    // with the same start address the same length as us. This makes them
    // simply look like repeated entries in the array and makes searching for
    // them with lower_bound/upper_bound work as expected.
    if (length != 0) {
      SourceLines::reverse_iterator it = source_lines_.rbegin();
      for (; it != source_lines_.rend(); ++it) {
        if (it->size != 0)
          break;
        if (it->address.value() != rva) {
          LOG(ERROR) << "Encountered zero-length line number with "
                     << "inconsistent address.";
          return false;
        }
        it->size = length;
      }
    }

    source_lines_.push_back(SourceLine(source_file_name,
                                       line,
                                       core::RelativeAddress(rva),
                                       length));
  }

  return true;
}

bool LineInfo::Visit(
    core::RelativeAddress address, size_t size, size_t count) {
  // Visiting a range of size zero is a nop.
  if (size == 0)
    return true;

  // Create a dummy 'source line' for the search.
  SourceLine visit_source_line(NULL, 0, address, size);

  SourceLines::iterator begin_it =
      std::lower_bound(source_lines_.begin(),
                       source_lines_.end(),
                       visit_source_line,
                       SourceLineAddressComparator());

  SourceLines::iterator end_it =
      std::upper_bound(source_lines_.begin(),
                       source_lines_.end(),
                       visit_source_line,
                       SourceLineAddressComparator());

  SourceLines::iterator it = begin_it;
  RelativeAddressRange visit(address, size);
  for (; it != end_it; ++it) {
    RelativeAddressRange range(it->address, it->size);
    if (visit.Intersects(range)) {
      // We use saturation arithmetic here as overflow is a real possibility in
      // long trace files.
      it->visit_count =
          std::min(it->visit_count,
                   std::numeric_limits<uint32>::max() - count) + count;
    }
  }

  return true;
}

}  // namespace grinder
