#!/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.

"""Symlinks files generated by Bazel into _tulsi-includes for indexing."""

import json
import os
import shutil
import sys


class Installer(object):
  """Symlinks generated files into _tulsi-includes."""

  def __init__(self, bazel_exec_root, preserve_tulsi_includes=True,
               output_root=None):
    """Initializes the installer with the proper Bazel paths."""

    self.bazel_exec_root = bazel_exec_root
    self.preserve_tulsi_includes = preserve_tulsi_includes
    # The folder must begin with an underscore as otherwise Bazel will delete
    # it whenever it builds. See tulsi_aspects.bzl for futher explanation.
    if not output_root:
      output_root = bazel_exec_root
    self.tulsi_root = os.path.join(output_root, '_tulsi-includes')

  def PrepareTulsiIncludes(self):
    """Creates tulsi includes, possibly removing the old folder."""

    tulsi_root = self.tulsi_root
    if not self.preserve_tulsi_includes and os.path.exists(tulsi_root):
      shutil.rmtree(tulsi_root)
    if not os.path.exists(tulsi_root):
      os.mkdir(tulsi_root)

  def InstallForTulsiouts(self, tulsiouts):
    """Creates tulsi includes and symlinks generated sources."""
    self.PrepareTulsiIncludes()

    for file_path in tulsiouts:
      try:
        output_data = json.load(open(file_path))
        self.InstallForData(output_data)
      except (ValueError, IOError) as e:
        print('Failed to load output data file "%s". %s'
              % (file_path, e))

  def InstallForData(self, output_data):
    """Symlinks generated sources present in the output_data."""
    bazel_exec_root = self.bazel_exec_root
    tulsi_root = self.tulsi_root

    for gs in output_data['generated_sources']:
      real_path, link_path = gs
      src = os.path.join(bazel_exec_root, real_path)

      # Bazel outputs are not guaranteed to be created if nothing references
      # them. This check skips the processing if an output was declared
      # but not created.
      if not os.path.exists(src):
        continue

      # The /x/x/ part is here to match the number of directory components
      # between tulsi root and bazel root. See tulsi_aspects.bzl for futher
      # explanation.
      dst = os.path.join(tulsi_root, 'x/x/', link_path)

      dst_dir = os.path.dirname(dst)
      if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)

      # It's important to use lexists() here in case dst is a broken symlink
      # (in which case exists() would return False).
      if os.path.lexists(dst):
        # Don't need to do anything if the link hasn't changed.
        if os.readlink(dst) == src:
          continue

        # Link changed; must remove it otherwise os.symlink will fail.
        os.unlink(dst)

      os.symlink(src, dst)


if __name__ == '__main__':
  if len(sys.argv) <= 2:
    sys.stderr.write('usage: %s <bazel exec root> <preserve tulsi includes?> '
                     '<.tulsiouts JSON files>\n' % sys.argv[0])
    exit(1)

  preserve = sys.argv[2] == 'True'
  Installer(sys.argv[1], preserve).InstallForTulsiouts(sys.argv[3:])
