#!/usr/bin/env python
#
# Copyright 2019 The Cobalt 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.
"""A portable interface for symlinking."""

import argparse
import os
import shutil
import sys

from starboard.tools import util
from starboard.tools import win_symlink

# This file is still executed with Python2 in CI.
# pylint:disable=consider-using-f-string


def IsWindows():
  return sys.platform in ['win32', 'cygwin']


def ToLongPath(path):
  """Converts to a path that supports long filenames."""
  if IsWindows():
    return win_symlink.ToDevicePath(path)
  else:
    return path


def IsSymLink(path):
  """Platform neutral version os os.path.islink()."""
  if IsWindows():
    return win_symlink.IsReparsePoint(path)
  else:
    return os.path.islink(path)


def MakeSymLink(target_path, link_path):
  """Makes a symlink.

  Args:
    target_path: target path to be linked to
    link_path: path to place the link

  Returns:
    None
  """
  if IsWindows():
    win_symlink.CreateReparsePoint(target_path, link_path)
  else:
    util.MakeDirs(os.path.dirname(link_path))
    os.symlink(target_path, link_path)


def ReadSymLink(link_path):
  """Returns the path (abs. or rel.) to the folder referred to by link_path."""
  if IsWindows():
    path = win_symlink.ReadReparsePoint(link_path)
  else:
    try:
      path = os.readlink(link_path)
    except OSError:
      path = None
  return path


def DelSymLink(link_path):
  if IsWindows():
    win_symlink.UnlinkReparsePoint(link_path)
  else:
    os.unlink(link_path)


def Rmtree(path):
  """See Rmtree() for documentation of this function."""
  if IsWindows():
    func = win_symlink.RmtreeShallow
  elif not os.path.islink(path):
    func = shutil.rmtree
  else:
    os.unlink(path)
    return
  if os.path.exists(path) or os.path.islink(path):
    func(path)


def OsWalk(root_dir, topdown=True, onerror=None, followlinks=False):
  if IsWindows():
    return win_symlink.OsWalk(root_dir, topdown, onerror, followlinks)
  else:
    return os.walk(root_dir, topdown, onerror, followlinks)


def _CreateArgumentParser():
  """Creates an argument parser for port_symlink."""

  class MyParser(argparse.ArgumentParser):

    def error(self, message):
      sys.stderr.write('error: {}\n'.format(message))
      self.print_help()
      sys.exit(2)

  help_msg = ('Example 1:\n'
              '  python port_link.py --link "target_path" "link_path"\n\n'
              'Example 2:\n'
              '  python port_link.py --link "../target_path" "link_path"\n\n')
  # Enables new lines in the description and epilog.
  formatter_class = argparse.RawDescriptionHelpFormatter
  parser = MyParser(epilog=help_msg, formatter_class=formatter_class)
  parser.add_argument(
      '--link',
      help='The target path and link path to be used when '
      'creating the symbolic link.',
      metavar='"path"',
      nargs=2)
  parser.add_argument(
      '-f',
      '--force',
      action='store_true',
      help='Force the symbolic link to be created, removing existing files and '
      'directories if needed.')
  group = parser.add_mutually_exclusive_group(required=True)
  group.add_argument(
      '-a',
      '--use_absolute_path',
      action='store_true',
      help='Generated symlink is stored as an absolute path.')
  group.add_argument(
      '-r',
      '--use_relative_path',
      action='store_true',
      help='Generated symlink is stored as a relative path.')
  return parser


def main():
  util.SetupDefaultLoggingConfig()
  parser = _CreateArgumentParser()
  args = parser.parse_args()

  target_path, link_path = args.link

  if args.force:
    Rmtree(link_path)
  if args.use_absolute_path:
    target_path = os.path.abspath(target_path)
  elif args.use_relative_path:
    # os.path.relpath() requires its second parameter be a directory. If our
    # target is a file, i.e. the link we will be creating should be to a file,
    # we need to calculate the relative path between our target and the
    # directory that our link will reside in, not the full path to the link
    # itself. If we do not, our relative path will ascend one level too far.
    # This is visible in the following examples.
    #
    # os.path.relpath(
    #     '/target/file.txt', '/link/file.txt') = '../../target/file.txt' [bad]
    #
    # os.path.relpath(
    #     '/target/file.txt', '/link')          = '../target/file.txt'   [good]
    if os.path.isfile(target_path):
      relative_link_path = os.path.dirname(link_path)
    else:
      relative_link_path = link_path
    target_path = os.path.relpath(target_path, relative_link_path)
  MakeSymLink(target_path=target_path, link_path=link_path)


if __name__ == '__main__':
  main()
