// Copyright (c) 2006, Google Inc.
// 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.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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.

#import <Foundation/Foundation.h>
#include <sys/stat.h>
#include <map>
#include <string>
#include <iostream>
#include <fstream>
#include <utility>

#include "google_breakpad/processor/basic_source_line_resolver.h"
#include "google_breakpad/processor/minidump.h"
#include "google_breakpad/processor/system_info.h"
#include "processor/pathname_stripper.h"

#include "on_demand_symbol_supplier.h"
#include "common/mac/dump_syms.h"

using std::map;
using std::string;

using google_breakpad::OnDemandSymbolSupplier;
using google_breakpad::PathnameStripper;
using google_breakpad::SymbolSupplier;
using google_breakpad::SystemInfo;

OnDemandSymbolSupplier::OnDemandSymbolSupplier(const string& search_dir,
                                               const string& symbol_search_dir)
  : search_dir_(search_dir) {
  NSFileManager* mgr = [NSFileManager defaultManager];
  size_t length = symbol_search_dir.length();
  if (length) {
    // Load all sym files in symbol_search_dir into our module_file_map
    // A symbol file always starts with a line like this:
    // MODULE mac x86 BBF0A8F9BEADDD2048E6464001CA193F0 GoogleDesktopDaemon
    // or
    // MODULE mac ppc BBF0A8F9BEADDD2048E6464001CA193F0 GoogleDesktopDaemon
    const char* symbolSearchStr = symbol_search_dir.c_str();
    NSString* symbolSearchPath = 
      [mgr stringWithFileSystemRepresentation:symbolSearchStr 
                                       length:strlen(symbolSearchStr)];
    NSDirectoryEnumerator* dirEnum = [mgr enumeratorAtPath:symbolSearchPath];
    NSString* fileName;
    NSCharacterSet* hexSet = 
      [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEF"];
    NSCharacterSet* newlineSet = 
      [NSCharacterSet characterSetWithCharactersInString:@"\r\n"];
    while ((fileName = [dirEnum nextObject])) {
      // Check to see what type of file we have
      NSDictionary* attrib = [dirEnum fileAttributes];
      NSString* fileType = [attrib objectForKey:NSFileType];
      if ([fileType isEqualToString:NSFileTypeDirectory]) {
        // Skip subdirectories
        [dirEnum skipDescendents];
      } else {
        NSString* filePath = [symbolSearchPath stringByAppendingPathComponent:fileName];
        NSString* dataStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
        if (dataStr) {
          // Check file to see if it is of appropriate type, and grab module
          // name.
          NSScanner* scanner = [NSScanner scannerWithString:dataStr];
          BOOL goodScan = [scanner scanString:@"MODULE mac " intoString:nil];
          if (goodScan) {
            goodScan = ([scanner scanString:@"x86 " intoString:nil] ||
                        [scanner scanString:@"x86_64 " intoString:nil] ||
                        [scanner scanString:@"ppc " intoString:nil]);
            if (goodScan) {
              NSString* moduleID;
              goodScan = [scanner scanCharactersFromSet:hexSet 
                                             intoString:&moduleID];
              if (goodScan) {
                // Module IDs are always 33 chars long
                goodScan = [moduleID length] == 33;
                if (goodScan) {
                  NSString* moduleName;
                  goodScan = [scanner scanUpToCharactersFromSet:newlineSet 
                                                     intoString:&moduleName];
                  if (goodScan) {
                    goodScan = [moduleName length] > 0;
                    if (goodScan) {
                      const char* moduleNameStr = [moduleName UTF8String];
                      const char* filePathStr = [filePath fileSystemRepresentation];
                      // Map our file
                      module_file_map_[moduleNameStr] = filePathStr;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

SymbolSupplier::SymbolResult
OnDemandSymbolSupplier::GetSymbolFile(const CodeModule* module,
                                      const SystemInfo* system_info,
                                      string* symbol_file) {
  string path(GetModuleSymbolFile(module));

  if (path.empty()) {
    if (!GenerateSymbolFile(module, system_info))
      return NOT_FOUND;

    path = GetModuleSymbolFile(module);
  }

  if (path.empty())
    return NOT_FOUND;

  *symbol_file = path;
  return FOUND;
}

SymbolSupplier::SymbolResult
OnDemandSymbolSupplier::GetSymbolFile(const CodeModule* module,
                                      const SystemInfo* system_info,
                                      string* symbol_file,
                                      string* symbol_data) {
  SymbolSupplier::SymbolResult s = GetSymbolFile(module,
                                                 system_info,
                                                 symbol_file);


  if (s == FOUND) {
    std::ifstream in(symbol_file->c_str());
    getline(in, *symbol_data, std::string::traits_type::to_char_type(
                std::string::traits_type::eof()));
    in.close();
  }

  return s;
}

SymbolSupplier::SymbolResult
OnDemandSymbolSupplier::GetCStringSymbolData(const CodeModule* module,
                                             const SystemInfo* system_info,
                                             string* symbol_file,
                                             char** symbol_data,
                                             size_t* symbol_data_size) {
  std::string symbol_data_string;
  SymbolSupplier::SymbolResult result = GetSymbolFile(module,
                                                      system_info,
                                                      symbol_file,
                                                      &symbol_data_string);
  if (result == FOUND) {
    *symbol_data_size = symbol_data_string.size() + 1;
    *symbol_data = new char[*symbol_data_size];
    if (*symbol_data == NULL) {
      // Should return INTERRUPT on memory allocation failure.
      return INTERRUPT;
    }
    memcpy(*symbol_data, symbol_data_string.c_str(), symbol_data_string.size());
    (*symbol_data)[symbol_data_string.size()] = '\0';
    memory_buffers_.insert(make_pair(module->code_file(), *symbol_data));
  }
  return result;
}

void OnDemandSymbolSupplier::FreeSymbolData(const CodeModule* module) {
  map<string, char*>::iterator it = memory_buffers_.find(module->code_file());
  if (it != memory_buffers_.end()) {
    delete [] it->second;
    memory_buffers_.erase(it);
  }
}

string OnDemandSymbolSupplier::GetLocalModulePath(const CodeModule* module) {
  NSFileManager* mgr = [NSFileManager defaultManager];
  const char* moduleStr = module->code_file().c_str();
  NSString* modulePath =
    [mgr stringWithFileSystemRepresentation:moduleStr length:strlen(moduleStr)];
  const char* searchStr = search_dir_.c_str();
  NSString* searchDir =
    [mgr stringWithFileSystemRepresentation:searchStr length:strlen(searchStr)];

  if ([mgr fileExistsAtPath:modulePath])
    return module->code_file();

  // If the module is not found, try to start appending the components to the
  // search string and stop if a file (not dir) is found or all components
  // have been appended
  NSArray* pathComponents = [modulePath componentsSeparatedByString:@"/"];
  size_t count = [pathComponents count];
  NSMutableString* path = [NSMutableString string];

  for (size_t i = 0; i < count; ++i) {
    [path setString:searchDir];

    for (size_t j = 0; j < i + 1; ++j) {
      size_t idx = count - 1 - i + j;
      [path appendFormat:@"/%@", [pathComponents objectAtIndex:idx]];
    }

    BOOL isDir;
    if ([mgr fileExistsAtPath:path isDirectory:&isDir] && (!isDir)) {
      return [path fileSystemRepresentation];
    }
  }

  return "";
}

string OnDemandSymbolSupplier::GetModulePath(const CodeModule* module) {
  return module->code_file();
}

string OnDemandSymbolSupplier::GetNameForModule(const CodeModule* module) {
  return PathnameStripper::File(module->code_file());
}

string OnDemandSymbolSupplier::GetModuleSymbolFile(const CodeModule* module) {
  string name(GetNameForModule(module));
  map<string, string>::iterator result = module_file_map_.find(name);

  return (result == module_file_map_.end()) ? "" : (*result).second;
}

static float GetFileModificationTime(const char* path) {
  float result = 0;
  struct stat file_stat;
  if (stat(path, &file_stat) == 0)
    result = (float)file_stat.st_mtimespec.tv_sec +
      (float)file_stat.st_mtimespec.tv_nsec / 1.0e9f;

  return result;
}

bool OnDemandSymbolSupplier::GenerateSymbolFile(const CodeModule* module,
                                                const SystemInfo* system_info) {
  bool result = true;
  string name = GetNameForModule(module);
  string module_path = GetLocalModulePath(module);
  NSString* symbol_path = [NSString stringWithFormat:@"/tmp/%s.%s.sym",
    name.c_str(), system_info->cpu.c_str()];

  if (module_path.empty())
    return false;

  // Check if there's already a symbol file cached.  Ensure that the file is
  // newer than the module.  Otherwise, generate a new one.
  BOOL generate_file = YES;
  if ([[NSFileManager defaultManager] fileExistsAtPath:symbol_path]) {
    // Check if the module file is newer than the saved symbols
    float cache_time =
      GetFileModificationTime([symbol_path fileSystemRepresentation]);
    float module_time =
      GetFileModificationTime(module_path.c_str());

    if (cache_time > module_time)
      generate_file = NO;
  }

  if (generate_file) {
    DumpSymbols dump(ALL_SYMBOL_DATA, false);
    if (dump.Read(module_path)) {
      // What Breakpad calls "x86" should be given to the system as "i386".
      std::string architecture;
      if (system_info->cpu.compare("x86") == 0) {
        architecture = "i386";
      } else {
        architecture = system_info->cpu;
      }

      if (dump.SetArchitecture(architecture)) {
        std::fstream file([symbol_path fileSystemRepresentation],
                          std::ios_base::out | std::ios_base::trunc);
        dump.WriteSymbolFile(file);
      } else {
        printf("Architecture %s not available for %s\n",
               system_info->cpu.c_str(), name.c_str());
        result = false;
      }
    } else {
      printf("Unable to open %s\n", module_path.c_str());
      result = false;
    }
  }

  // Add the mapping
  if (result)
    module_file_map_[name] = [symbol_path fileSystemRepresentation];

  return result;
}
