#!/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 logging
import os
import shutil
import sys

import _env  # pylint: disable=relative-import,unused-import

from starboard.tools import util


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


def ToLongPath(path):
  """Converts to a path that supports long filenames."""
  if IsWindows():
    # pylint: disable=g-import-not-at-top
    from starboard.tools import win_symlink
    return win_symlink.ToDevicePath(path)
  else:
    return path

def IsSymLink(path):
  """Platform neutral version os os.path.islink()"""
  if IsWindows():
    # pylint: disable=g-import-not-at-top
    from starboard.tools import win_symlink
    return win_symlink.IsReparsePoint(path)
  else:
    return os.path.islink(path)


def MakeSymLink(from_folder, link_folder):
  """Makes a symlink.

  Args:
    from_folder: Path to the actual folder
    link_folder: Path to the link

  Returns:
    None
  """
  if IsWindows():
    # pylint: disable=g-import-not-at-top
    from starboard.tools import win_symlink
    win_symlink.CreateReparsePoint(from_folder, link_folder)
  else:
    util.MakeDirs(os.path.dirname(link_folder))
    os.symlink(from_folder, link_folder)


def ReadSymLink(link_path):
  """Returns the path (abs. or rel.) to the folder referred to by link_path."""
  if IsWindows():
    # pylint: disable=g-import-not-at-top
    from starboard.tools import win_symlink
    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():
    # pylint: disable=g-import-not-at-top
    from starboard.tools import win_symlink
    win_symlink.UnlinkReparsePoint(link_path)
  else:
    os.unlink(link_path)


def Rmtree(path):
  """See Rmtree() for documentation of this function."""
  if not os.path.exists(path):
    return
  if IsWindows():
    # pylint: disable=g-import-not-at-top
    from starboard.tools import win_symlink
    win_symlink.RmtreeShallow(path)
  else:
    if os.path.islink(path):
      os.unlink(path)
    else:
      shutil.rmtree(path)


def OsWalk(root_dir, topdown=True, onerror=None, followlinks=False):
  if IsWindows():
    # pylint: disable=g-import-not-at-top
    from starboard.tools import win_symlink
    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: %s\n' % message)
      self.print_help()
      sys.exit(2)
  help_msg = (
      'Example 1:\n'
      '  python port_link.py --link "actual_folder_path" "link_path"\n\n'
      'Example 2:\n'
      '  python port_link.py --link "../actual_folder_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(
      '-a',
      '--use_absolute_symlinks',
      action='store_true',
      help='Generated symlinks are stored as absolute paths.')
  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('--link',
                     help='Issues an scp command to upload src to remote_dst',
                     metavar='"path"',
                     nargs=2)
  return parser


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

  folder_path, link_path = args.link
  if args.use_absolute_symlinks:
    folder_path = os.path.abspath(folder_path)
    link_path = os.path.abspath(link_path)
  if '.' in folder_path:
    d1 = os.path.abspath(folder_path)
  else:
    d1 = os.path.abspath(os.path.join(link_path, folder_path))
  if not os.path.isdir(d1):
    logging.warning('%s is not a directory.', d1)
  if args.force:
    Rmtree(link_path)
  MakeSymLink(from_folder=folder_path, link_folder=link_path)


if __name__ == '__main__':
  main()
