//===-- SymbolVendorMacOSX.cpp ----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "SymbolVendorMacOSX.h"

#include <string.h>

#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/XML.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// SymbolVendorMacOSX constructor
//----------------------------------------------------------------------
SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp)
    : SymbolVendor(module_sp) {}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SymbolVendorMacOSX::~SymbolVendorMacOSX() {}

static bool UUIDsMatch(Module *module, ObjectFile *ofile,
                       lldb_private::Stream *feedback_strm) {
  if (module && ofile) {
    // Make sure the UUIDs match
    lldb_private::UUID dsym_uuid;

    if (!ofile->GetUUID(&dsym_uuid)) {
      if (feedback_strm) {
        feedback_strm->PutCString(
            "warning: failed to get the uuid for object file: '");
        ofile->GetFileSpec().Dump(feedback_strm);
        feedback_strm->PutCString("\n");
      }
      return false;
    }

    if (dsym_uuid == module->GetUUID())
      return true;

    // Emit some warning messages since the UUIDs do not match!
    if (feedback_strm) {
      feedback_strm->PutCString(
          "warning: UUID mismatch detected between modules:\n    ");
      module->GetUUID().Dump(feedback_strm);
      feedback_strm->PutChar(' ');
      module->GetFileSpec().Dump(feedback_strm);
      feedback_strm->PutCString("\n    ");
      dsym_uuid.Dump(feedback_strm);
      feedback_strm->PutChar(' ');
      ofile->GetFileSpec().Dump(feedback_strm);
      feedback_strm->EOL();
    }
  }
  return false;
}

void SymbolVendorMacOSX::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance);
}

void SymbolVendorMacOSX::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

lldb_private::ConstString SymbolVendorMacOSX::GetPluginNameStatic() {
  static ConstString g_name("macosx");
  return g_name;
}

const char *SymbolVendorMacOSX::GetPluginDescriptionStatic() {
  return "Symbol vendor for MacOSX that looks for dSYM files that match "
         "executables.";
}

//----------------------------------------------------------------------
// CreateInstance
//
// Platforms can register a callback to use when creating symbol vendors to
// allow for complex debug information file setups, and to also allow for
// finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor *
SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
                                   lldb_private::Stream *feedback_strm) {
  if (!module_sp)
    return NULL;

  ObjectFile *obj_file = module_sp->GetObjectFile();
  if (!obj_file)
    return NULL;

  static ConstString obj_file_macho("mach-o");
  ConstString obj_name = obj_file->GetPluginName();
  if (obj_name != obj_file_macho)
    return NULL;

  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
  Timer scoped_timer(func_cat,
                     "SymbolVendorMacOSX::CreateInstance (module = %s)",
                     module_sp->GetFileSpec().GetPath().c_str());
  SymbolVendorMacOSX *symbol_vendor = new SymbolVendorMacOSX(module_sp);
  if (symbol_vendor) {
    char path[PATH_MAX];
    path[0] = '\0';

    // Try and locate the dSYM file on Mac OS X
    static Timer::Category func_cat2(
        "SymbolVendorMacOSX::CreateInstance() locate dSYM");
    Timer scoped_timer2(
        func_cat2,
        "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
        module_sp->GetFileSpec().GetPath().c_str());

    // First check to see if the module has a symbol file in mind already. If
    // it does, then we MUST use that.
    FileSpec dsym_fspec(module_sp->GetSymbolFileFileSpec());

    ObjectFileSP dsym_objfile_sp;
    if (!dsym_fspec) {
      // No symbol file was specified in the module, lets try and find one
      // ourselves.
      FileSpec file_spec = obj_file->GetFileSpec();
      if (!file_spec)
        file_spec = module_sp->GetFileSpec();

      ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
      module_spec.GetUUID() = module_sp->GetUUID();
      dsym_fspec = Symbols::LocateExecutableSymbolFile(module_spec);
      if (module_spec.GetSourceMappingList().GetSize())
        module_sp->GetSourceMappingList().Append(
            module_spec.GetSourceMappingList(), true);
    }

    if (dsym_fspec) {
      DataBufferSP dsym_file_data_sp;
      lldb::offset_t dsym_file_data_offset = 0;
      dsym_objfile_sp = ObjectFile::FindPlugin(
          module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(),
          dsym_file_data_sp, dsym_file_data_offset);
      if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) {
        // We need a XML parser if we hope to parse a plist...
        if (XMLDocument::XMLEnabled()) {
          char dsym_path[PATH_MAX];
          if (module_sp->GetSourceMappingList().IsEmpty() &&
              dsym_fspec.GetPath(dsym_path, sizeof(dsym_path))) {
            lldb_private::UUID dsym_uuid;
            if (dsym_objfile_sp->GetUUID(&dsym_uuid)) {
              std::string uuid_str = dsym_uuid.GetAsString();
              if (!uuid_str.empty()) {
                char *resources = strstr(dsym_path, "/Contents/Resources/");
                if (resources) {
                  char dsym_uuid_plist_path[PATH_MAX];
                  resources[strlen("/Contents/Resources/")] = '\0';
                  snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path),
                           "%s%s.plist", dsym_path, uuid_str.c_str());
                  FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
                  if (dsym_uuid_plist_spec.Exists()) {
                    ApplePropertyList plist(dsym_uuid_plist_path);
                    if (plist) {
                      std::string DBGBuildSourcePath;
                      std::string DBGSourcePath;

                      // DBGSourcePathRemapping is a dictionary in the plist
                      // with keys which are DBGBuildSourcePath file paths and
                      // values which are DBGSourcePath file paths

                      StructuredData::ObjectSP plist_sp =
                          plist.GetStructuredData();
                      if (plist_sp.get() && plist_sp->GetAsDictionary() &&
                          plist_sp->GetAsDictionary()->HasKey(
                              "DBGSourcePathRemapping") &&
                          plist_sp->GetAsDictionary()
                              ->GetValueForKey("DBGSourcePathRemapping")
                              ->GetAsDictionary()) {

                        // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
                        // If DBGVersion 2, strip last two components of path remappings from
                        //                  entries to fix an issue with a specific set of
                        //                  DBGSourcePathRemapping entries that lldb worked
                        //                  with.
                        // If DBGVersion 3, trust & use the source path remappings as-is.
                        //

                        bool new_style_source_remapping_dictionary = false;
                        bool do_truncate_remapping_names = false;
                        std::string original_DBGSourcePath_value =
                            DBGSourcePath;
                        if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) {
                          std::string version_string =
                              plist_sp->GetAsDictionary()
                                  ->GetValueForKey("DBGVersion")
                                  ->GetStringValue("");
                          if (!version_string.empty() &&
                              isdigit(version_string[0])) {
                            int version_number = atoi(version_string.c_str());
                            if (version_number > 1) {
                              new_style_source_remapping_dictionary = true;
                            }
                            if (version_number == 2) {
                                do_truncate_remapping_names = true;
                            }
                          }
                        }

                        StructuredData::Dictionary *remappings_dict =
                            plist_sp->GetAsDictionary()
                                ->GetValueForKey("DBGSourcePathRemapping")
                                ->GetAsDictionary();
                        remappings_dict->ForEach(
                            [&module_sp, new_style_source_remapping_dictionary,
                             original_DBGSourcePath_value, do_truncate_remapping_names](
                                ConstString key,
                                StructuredData::Object *object) -> bool {
                              if (object && object->GetAsString()) {

                                // key is DBGBuildSourcePath
                                // object is DBGSourcePath
                                std::string DBGSourcePath =
                                    object->GetStringValue();
                                if (new_style_source_remapping_dictionary ==
                                        false &&
                                    !original_DBGSourcePath_value.empty()) {
                                  DBGSourcePath = original_DBGSourcePath_value;
                                }
                                if (DBGSourcePath[0] == '~') {
                                  FileSpec resolved_source_path(
                                      DBGSourcePath.c_str(), true);
                                  DBGSourcePath =
                                      resolved_source_path.GetPath();
                                }
                                module_sp->GetSourceMappingList().Append(
                                    key, ConstString(DBGSourcePath), true);
                                // With version 2 of DBGSourcePathRemapping, we
                                // can chop off the last two filename parts
                                // from the source remapping and get a more
                                // general source remapping that still works.
                                // Add this as another option in addition to
                                // the full source path remap.
                                if (do_truncate_remapping_names) {
                                  FileSpec build_path(key.AsCString(), false);
                                  FileSpec source_path(DBGSourcePath.c_str(), false);
                                  build_path.RemoveLastPathComponent();
                                  build_path.RemoveLastPathComponent();
                                  source_path.RemoveLastPathComponent();
                                  source_path.RemoveLastPathComponent();
                                  module_sp->GetSourceMappingList().Append(
                                      ConstString(build_path.GetPath().c_str()),
                                      ConstString(source_path.GetPath().c_str()), true);
                                }
                              }
                              return true;
                            });
                      }

                      // If we have a DBGBuildSourcePath + DBGSourcePath pair,
                      // append those to the source path remappings.

                      plist.GetValueAsString("DBGBuildSourcePath",
                                             DBGBuildSourcePath);
                      plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
                      if (!DBGBuildSourcePath.empty() &&
                          !DBGSourcePath.empty()) {
                        if (DBGSourcePath[0] == '~') {
                          FileSpec resolved_source_path(DBGSourcePath.c_str(),
                                                        true);
                          DBGSourcePath = resolved_source_path.GetPath();
                        }
                        module_sp->GetSourceMappingList().Append(
                            ConstString(DBGBuildSourcePath),
                            ConstString(DBGSourcePath), true);
                      }
                    }
                  }
                }
              }
            }
          }
        }

        symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
        return symbol_vendor;
      }
    }

    // Just create our symbol vendor using the current objfile as this is
    // either an executable with no dSYM (that we could locate), an executable
    // with a dSYM that has a UUID that doesn't match.
    symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
  }
  return symbol_vendor;
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
ConstString SymbolVendorMacOSX::GetPluginName() {
  return GetPluginNameStatic();
}

uint32_t SymbolVendorMacOSX::GetPluginVersion() { return 1; }
