#!/usr/bin/python3
# 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 bazel-tulsi-includes for indexing."""


import json
import os
import shutil
import sys


class Installer(object):
  """Symlinks generated files into bazel-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, 'bazel-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:])
