#!/usr/bin/python
# Copyright 2018 The Tulsi Authors. All rights reserved.
#
# 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
#
#      http://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.

"""Bootstraps the presence and setup of ~/.lldbinit-tulsiproj."""

import os
import shutil
import StringIO
import sys


TULSI_LLDBINIT_FILE = os.path.expanduser('~/.lldbinit-tulsiproj')


class BootstrapLLDBInit(object):
  """Bootstrap Xcode's preferred lldbinit for Bazel debugging."""

  def _ExtractLLDBInitContent(self, lldbinit_path, source_string):
    """Extracts non-Tulsi content in a given lldbinit if needed.

    Args:
      lldbinit_path: Absolute path to the lldbinit we are writing to.
      source_string: String that we wish to write to lldbinit.

    Returns:
      (int, [string]): A tuple featuring the status code along with the list
                       of strings representing content to write to lldbinit
                       that does not account for the Tulsi-generated strings.
                       Status code will be 0 if Tulsi-generated strings are
                       not all there. Status code will be 1 if all Tulsi
                       strings were accounted for. Status code will be 2 if
                       the lldbinit file could not be found.
    """
    if not os.path.isfile(lldbinit_path):
      return (2, [])
    content = []
    with open(lldbinit_path) as f:
      ignoring = False

      # Split on the newline. This works as long as the last string isn't
      # suffixed with \n.
      source_lines = source_string.split('\n')

      source_idx = 0

      # If the last line was suffixed with \n, last elements would be length
      # minus 2, accounting for the extra \n.
      source_last = len(source_lines) - 1

      for line in f:

        # For each line found matching source_string, increment the iterator
        # and do not append that line to the list.
        if source_lines[source_idx] in line:

          # If all lines were found, return an error code with empty content.
          if source_idx == source_last:
            return (1, [])

          # Increment for each matching line found.
          source_idx += 1
          ignoring = True
          continue

        if ignoring:

          # If the last line was found...
          if source_lines[source_last] in line:
            # Stop ignoring lines and continue appending to content.
            ignoring = False
          continue

        # If the line could not be found within source_string, append to the
        # content array.
        content.append(line)

    return (0, content)

  def _LinkTulsiLLDBInit(self):
    """Adds a reference to ~/.lldbinit-tulsiproj to the primary lldbinit file.

    Xcode 8+ executes the contents of the first available lldbinit on startup.
    To help work around this, an external reference to ~/.lldbinit-tulsiproj is
    added to that lldbinit. This causes Xcode's lldb-rpc-server to load the
    possibly modified contents between Debug runs of any given app. Note that
    this only happens after a Debug session terminates; the cache is only fully
    invalidated after Xcode is relaunched.
    """

    # ~/.lldbinit-Xcode is the only lldbinit file that Xcode will read if it is
    # present, therefore it has priority.
    lldbinit_path = os.path.expanduser('~/.lldbinit-Xcode')
    if not os.path.isfile(lldbinit_path):
      # If ~/.lldbinit-Xcode does not exist, write the reference to
      # ~/.lldbinit-tulsiproj to ~/.lldbinit, the second lldbinit file that
      # Xcode will attempt to read if ~/.lldbinit-Xcode isn't present.
      lldbinit_path = os.path.expanduser('~/.lldbinit')

    # String that we plan to inject into this lldbinit.
    source_string = ('# <TULSI> LLDB bridge [:\n'
                     '# This was autogenerated by Tulsi in order to modify '
                     'LLDB source-maps at build time.\n'
                     'command source %s\n' % TULSI_LLDBINIT_FILE +
                     '# ]: <TULSI> LLDB bridge')

    # Retrieve the contents of lldbinit if applicable along with a return code.
    return_code, content = self._ExtractLLDBInitContent(lldbinit_path,
                                                        source_string)

    # If we should ignore the contents of this lldbinit, and it has the
    # association with ~/.lldbinit-tulsiproj that we want, do not modify it.
    if return_code != 0:
      return

    # Otherwise, print the existing contents of this ~/.lldbinit out without
    # any malformed tulsi lldbinit block, and add the correct tulsi lldbinit
    # block to the end of it.
    out = StringIO.StringIO()
    for line in content:
      out.write(line)

    # Add a newline after the source_string for protection from other elements
    # within the lldbinit file.
    out.write(source_string + '\n')

    with open(lldbinit_path, 'w') as outfile:
      out.seek(0)
      # Negative length to make copyfileobj write the whole file at once.
      shutil.copyfileobj(out, outfile, -1)

  def __init__(self):
    self._LinkTulsiLLDBInit()


if __name__ == '__main__':
  BootstrapLLDBInit()
  sys.exit(0)
