# Copyright (C) 2013 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 errno
import logging
import os
import shlex

from webkitpy.layout_tests.breakpad.dump_reader import DumpReader


_log = logging.getLogger(__name__)


class DumpReaderWin(DumpReader):
    """DumpReader for windows breakpad."""

    def __init__(self, host, build_dir):
        super(DumpReaderWin, self).__init__(host, build_dir)
        self._cdb_available = None

    def check_is_functional(self):
        return self._check_cdb_available()

    def _file_extension(self):
        return 'txt'

    def _get_pid_from_dump(self, dump_file):
        with self._host.filesystem.open_text_file_for_reading(dump_file) as f:
            crash_keys = dict([l.split(':', 1) for l in f.read().splitlines()])
            if 'pid' in crash_keys:
                return crash_keys['pid']
        return None

    def _get_stack_from_dump(self, dump_file):
        minidump = dump_file[:-3] + 'dmp'
        cmd = [self._cdb_path, '-y', self._build_dir, '-c', '.lines;.ecxr;k30;q', '-z', minidump]
        try:
            stack = self._host.executive.run_command(cmd)
        except:
            _log.warning('Failed to execute "%s"', ' '.join(cmd))
        else:
            return stack
        return None

    def _find_depot_tools_path(self):
        """Attempt to find depot_tools location in PATH."""
        for i in self._host.environ.get('PATH').split(os.pathsep):
            if os.path.isfile(os.path.join(i, 'gclient')):
                return i

    def _check_cdb_available(self):
        """Checks whether we can use cdb to symbolize minidumps."""
        if self._cdb_available is not None:
            return self._cdb_available

        CDB_LOCATION_TEMPLATES = [
            '%s\\Debugging Tools For Windows',
            '%s\\Debugging Tools For Windows (x86)',
            '%s\\Debugging Tools For Windows (x64)',
            '%s\\Windows Kits\\8.0\\Debuggers\\x86',
            '%s\\Windows Kits\\8.0\\Debuggers\\x64',
            '%s\\Windows Kits\\8.1\\Debuggers\\x86',
            '%s\\Windows Kits\\8.1\\Debuggers\\x64',
            '%s\\Windows Kits\\10\\Debuggers\\x86',
            '%s\\Windows Kits\\10\\Debuggers\\x64',
        ]

        program_files_directories = ['C:\\Program Files']
        program_files = self._host.environ.get('ProgramFiles')
        if program_files:
            program_files_directories.append(program_files)
        program_files = self._host.environ.get('ProgramFiles(x86)')
        if program_files:
            program_files_directories.append(program_files)

        possible_cdb_locations = []
        for template in CDB_LOCATION_TEMPLATES:
            for program_files in program_files_directories:
                possible_cdb_locations.append(template % program_files)

        gyp_defines = self._host.environ.get('GYP_DEFINES', [])
        if gyp_defines:
            gyp_defines = shlex.split(gyp_defines)
        if 'windows_sdk_path' in gyp_defines:
            possible_cdb_locations.extend([
                '%s\\Debuggers\\x86' % gyp_defines['windows_sdk_path'],
                '%s\\Debuggers\\x64' % gyp_defines['windows_sdk_path'],
            ])

        # Look in depot_tools win_toolchain too.
        depot_tools = self._find_depot_tools_path()
        if depot_tools:
            try:
                vs_files = os.path.join(depot_tools, 'win_toolchain', 'vs_files')
                for path in os.listdir(vs_files):
                    win_sdk = os.path.join(vs_files, path, 'win_sdk')
                    possible_cdb_locations.extend([
                        '%s\\Debuggers\\x86' % win_sdk,
                        '%s\\Debuggers\\x64' % win_sdk,
                    ])
            except OSError as error:
                if error.errno != errno.ENOENT:
                    raise

        for cdb_path in possible_cdb_locations:
            cdb = self._host.filesystem.join(cdb_path, 'cdb.exe')
            try:
                _ = self._host.executive.run_command([cdb, '-version'])
            except:
                pass
            else:
                self._cdb_path = cdb
                self._cdb_available = True
                return self._cdb_available

        _log.warning("CDB is not installed; can't symbolize minidumps.")
        _log.warning('')
        self._cdb_available = False
        return self._cdb_available
