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

from __future__ import print_function
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) < 3:
    sys.stderr.write('usage: %s <bazel exec root> '
                     '<.tulsiouts JSON files>\n' % sys.argv[0])
    exit(1)

  Installer(sys.argv[1]).InstallForTulsiouts(sys.argv[2:])
