# Copyright 2020 The Pigweed Authors
#
# 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
#
#     https://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.
"""Heap visualizer of ASCII characters."""

import argparse
import sys
import math
import logging
from typing import Optional
from dataclasses import dataclass
import coloredlogs  # type: ignore


@dataclass
class HeapBlock:
    """Building blocks for memory chunk allocated at heap."""
    size: int
    mem_offset: int
    next: Optional['HeapBlock'] = None


@dataclass
class HeapUsage:
    """Contains a linked list of allocated HeapBlocks."""
    begin: HeapBlock = HeapBlock(0, 0)

    def add_block(self, block):
        cur_block = self.begin.next
        prev_block = self.begin
        while cur_block is not None:
            if cur_block.mem_offset == block.mem_offset:
                return
            if cur_block.mem_offset < block.mem_offset:
                prev_block = cur_block
                cur_block = cur_block.next
            else:
                block.next = cur_block
                prev_block.next = block
                return
        prev_block.next = block

    def remove_block(self, address):
        cur_block = self.begin.next
        prev_block = self.begin
        while cur_block is not None:
            if cur_block.mem_offset == address:
                prev_block.next = cur_block.next
                return
            if cur_block.mem_offset < address:
                prev_block = cur_block
                cur_block = cur_block.next
            else:
                return


def add_parser_arguments(parser):
    parser.add_argument('--dump-file',
                        help=('dump file that contains a list of malloc and '
                              'free instructions. The format should be as '
                              'follows: "m <size> <address>" on a line for '
                              'each malloc called and "f <address>" on a line '
                              'for each free called.'),
                        required=True)

    parser.add_argument('--heap-low-address',
                        help=('lower address of the heap.'),
                        type=lambda x: int(x, 0),
                        required=True)

    parser.add_argument('--heap-high-address',
                        help=('higher address of the heap.'),
                        type=lambda x: int(x, 0),
                        required=True)

    parser.add_argument('--poison-enabled',
                        help=('if heap poison is enabled or not.'),
                        default=False,
                        action='store_true')

    parser.add_argument('--pointer-size',
                        help=('size of pointer on the machine.'),
                        default=4,
                        type=lambda x: int(x, 0))


_LEFT_HEADER_CHAR = '['
_RIGHT_HEADER_CHAR = ']'
_USED_CHAR = '*'
_FREE_CHAR = ' '
_CHARACTERS_PER_LINE = 64
_BYTES_PER_CHARACTER = 4
_LOG = logging.getLogger(__name__)


def _exit_due_to_file_not_found():
    _LOG.critical('Dump file location is not provided or dump file is not '
                  'found. Please specify a valid file in the argument.')
    sys.exit(1)


def _exit_due_to_bad_heap_info():
    _LOG.critical(
        'Heap low/high address is missing or invalid. Please put valid '
        'addresses in the argument.')
    sys.exit(1)


def visualize(dump_file=None,
              heap_low_address=None,
              heap_high_address=None,
              poison_enabled=False,
              pointer_size=4):
    """Visualization of heap usage."""
    # TODO(pwbug/236): Add standarized mechanisms to produce dump file and read
    # heap information from dump file.
    aligned_bytes = pointer_size
    header_size = pointer_size * 2

    try:
        if heap_high_address < heap_low_address:
            _exit_due_to_bad_heap_info()
        heap_size = heap_high_address - heap_low_address
    except TypeError:
        _exit_due_to_bad_heap_info()

    if poison_enabled:
        poison_offset = pointer_size
    else:
        poison_offset = 0

    try:
        allocation_dump = open(dump_file, 'r')
    except (FileNotFoundError, TypeError):
        _exit_due_to_file_not_found()

    heap_visualizer = HeapUsage()
    # Parse the dump file.
    for line in allocation_dump:
        info = line[:-1].split(' ')
        if info[0] == 'm':
            # Add a HeapBlock when malloc is called
            block = HeapBlock(
                int(math.ceil(float(info[1]) / aligned_bytes)) * aligned_bytes,
                int(info[2], 0) - heap_low_address)
            heap_visualizer.add_block(block)
        elif info[0] == 'f':
            # Remove the HeapBlock when free is called
            heap_visualizer.remove_block(int(info[1], 0) - heap_low_address)

    # next_block indicates the nearest HeapBlock that hasn't finished
    # printing.
    next_block = heap_visualizer.begin
    if next_block.next is None:
        next_mem_offset = heap_size + header_size + poison_offset + 1
        next_size = 0
    else:
        next_mem_offset = next_block.next.mem_offset
        next_size = next_block.next.size

    # Flags to indicate status of the 4 bytes going to be printed.
    is_left_header = False
    is_right_header = False
    is_used = False

    # Print overall heap information
    _LOG.info('%-40s%-40s', f'The heap starts at {hex(heap_low_address)}.',
              f'The heap ends at {hex(heap_high_address)}.')
    _LOG.info('%-40s%-40s', f'Heap size is {heap_size // 1024}k bytes.',
              f'Heap is aligned by {aligned_bytes} bytes.')
    if poison_offset != 0:
        _LOG.info(
            'Poison is enabled %d bytes before and after the usable '
            'space of each block.', poison_offset)
    else:
        _LOG.info('%-40s', 'Poison is disabled.')
    _LOG.info(
        '%-40s', 'Below is the visualization of the heap. '
        'Each character represents 4 bytes.')
    _LOG.info('%-40s', f"    '{_FREE_CHAR}' indicates free space.")
    _LOG.info('%-40s', f"    '{_USED_CHAR}' indicates used space.")
    _LOG.info(
        '%-40s', f"    '{_LEFT_HEADER_CHAR}' indicates header or "
        'poisoned space before the block.')
    _LOG.info('%-40s', f"    '{_RIGHT_HEADER_CHAR}' poisoned space after "
              'the block.')
    print()

    # Go over the heap space where there will be 64 characters each line.
    for line_base_address in range(0, heap_size, _CHARACTERS_PER_LINE *
                                   _BYTES_PER_CHARACTER):
        # Print the heap address of the current line.
        sys.stdout.write(f"{' ': <13}"
                         f'{hex(heap_low_address + line_base_address)}'
                         f"{f' (+{line_base_address}):': <12}")
        for line_offset in range(0,
                                 _CHARACTERS_PER_LINE * _BYTES_PER_CHARACTER,
                                 _BYTES_PER_CHARACTER):
            # Determine if the current 4 bytes is used, unused, or is a
            # header.
            # The case that we have went over the previous block and will
            # turn to the next block.
            current_address = line_base_address + line_offset
            if current_address == next_mem_offset + next_size + poison_offset:
                next_block = next_block.next
                # If this is the last block, set nextMemOffset to be over
                # the last byte of heap so that the rest of the heap will
                # be printed out as unused.
                # Otherwise set the next HeapBlock allocated.
                if next_block.next is None:
                    next_mem_offset = (heap_size + header_size +
                                       poison_offset + 1)
                    next_size = 0
                else:
                    next_mem_offset = next_block.next.mem_offset
                    next_size = next_block.next.size

            # Determine the status of the current 4 bytes.
            if (next_mem_offset - header_size - poison_offset <=
                    current_address < next_mem_offset):
                is_left_header = True
                is_right_header = False
                is_used = False
            elif (next_mem_offset <= current_address <
                  next_mem_offset + next_size):
                is_left_header = False
                is_right_header = False
                is_used = True
            elif (next_mem_offset + next_size <= current_address <
                  next_mem_offset + next_size + poison_offset):
                is_left_header = False
                is_right_header = True
                is_used = False
            else:
                is_left_header = False
                is_right_header = False
                is_used = False

            if is_left_header:
                sys.stdout.write(_LEFT_HEADER_CHAR)
            elif is_right_header:
                sys.stdout.write(_RIGHT_HEADER_CHAR)
            elif is_used:
                sys.stdout.write(_USED_CHAR)
            else:
                sys.stdout.write(_FREE_CHAR)
        sys.stdout.write('\n')

    allocation_dump.close()


def main():
    """A python script to visualize heap usage given a dump file."""
    parser = argparse.ArgumentParser(description=main.__doc__)
    add_parser_arguments(parser)
    # Try to use pw_cli logs, else default to something reasonable.
    try:
        import pw_cli.log  # pylint: disable=import-outside-toplevel
        pw_cli.log.install()
    except ImportError:
        coloredlogs.install(level='INFO',
                            level_styles={
                                'debug': {
                                    'color': 244
                                },
                                'error': {
                                    'color': 'red'
                                }
                            },
                            fmt='%(asctime)s %(levelname)s | %(message)s')
    visualize(**vars(parser.parse_args()))


if __name__ == "__main__":
    main()
