// 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;
}
