#!/usr/bin/env python3
#
# Copyright 2018 - The Android Open Source Project
#
# 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.

"""It is an AIDEGen sub task : IDE operation task!

Takes a project file path as input, after passing the needed check(file
existence, IDE type, etc.), launch the project in related IDE.

    Typical usage example:

    ide_util_obj = IdeUtil()
    if ide_util_obj.is_ide_installed():
        ide_util_obj.config_ide(project_file)
        ide_util_obj.launch_ide()
"""

import fnmatch
import glob
import logging
import os
import platform
import re
import subprocess

from aidegen import constant
from aidegen.lib import common_util
from aidegen.lib import config
from aidegen.lib import sdk_config

# Add 'nohup' to prevent IDE from being terminated when console is terminated.
_NOHUP = 'nohup'
_IGNORE_STD_OUT_ERR_CMD = '2>/dev/null >&2'
_IDEA_FOLDER = '.idea'
_IML_EXTENSION = '.iml'
_JDK_PATH_TOKEN = '@JDKpath'
_COMPONENT_END_TAG = '  </component>'
_ECLIPSE_WS = '~/Documents/AIDEGen_Eclipse_workspace'
_ALERT_CREATE_WS = ('AIDEGen will create a workspace at %s for Eclipse, '
                    'Enter `y` to allow AIDEgen to automatically create the '
                    'workspace for you. Otherwise, you need to select the '
                    'workspace after Eclipse is launched.\nWould you like '
                    'AIDEgen to automatically create the workspace for you?'
                    '(y/n)' % _ECLIPSE_WS)


class IdeUtil:
    """Provide a set of IDE operations, e.g., launch and configuration.

    Attributes:
        _ide: IdeBase derived instance, the related IDE object.

    For example:
        1. Check if IDE is installed.
        2. Config IDE, e.g. config code style, SDK path, and etc.
        3. Launch an IDE.
    """

    def __init__(self,
                 installed_path=None,
                 ide='j',
                 config_reset=False,
                 is_mac=False):
        logging.debug('IdeUtil with OS name: %s%s', platform.system(),
                      '(Mac)' if is_mac else '')
        self._ide = _get_ide(installed_path, ide, config_reset, is_mac)

    def is_ide_installed(self):
        """Checks if the IDE is already installed.

        Returns:
            True if IDE is installed already, otherwise False.
        """
        return self._ide.is_ide_installed()

    def launch_ide(self):
        """Launches the relative IDE by opening the passed project file."""
        return self._ide.launch_ide()

    def config_ide(self, project_abspath):
        """To config the IDE, e.g., setup code style, init SDK, and etc.

        Args:
            project_abspath: An absolute path of the project.
        """
        self._ide.project_abspath = project_abspath
        if self.is_ide_installed() and self._ide:
            self._ide.apply_optional_config()

    def get_default_path(self):
        """Gets IDE default installed path."""
        return self._ide.default_installed_path

    def ide_name(self):
        """Gets IDE name."""
        return self._ide.ide_name


class IdeBase:
    """The most base class of IDE, provides interface and partial path init.

    Attributes:
        _installed_path: String for the IDE binary path.
        _config_reset: Boolean, True for reset configuration, else not reset.
        _bin_file_name: String for IDE executable file name.
        _bin_paths: A list of all possible IDE executable file absolute paths.
        _ide_name: String for IDE name.
        _bin_folders: A list of all possible IDE installed paths.
        project_abspath: The absolute path of the project.

    For example:
        1. Check if IDE is installed.
        2. Launch IDE.
        3. Config IDE.
    """

    def __init__(self, installed_path=None, config_reset=False):
        self._installed_path = installed_path
        self._config_reset = config_reset
        self._ide_name = ''
        self._bin_file_name = ''
        self._bin_paths = []
        self._bin_folders = []
        self.project_abspath = ''

    def is_ide_installed(self):
        """Checks if IDE is already installed.

        Returns:
            True if IDE is installed already, otherwise False.
        """
        return bool(self._installed_path)

    def launch_ide(self):
        """Launches IDE by opening the passed project file."""
        _launch_ide(self.project_abspath, self._get_ide_cmd(), self._ide_name)

    def apply_optional_config(self):
        """Handles IDE relevant configs."""
        # Default does nothing, the derived classes know what need to config.

    @property
    def default_installed_path(self):
        """Gets IDE default installed path."""
        return ' '.join(self._bin_folders)

    @property
    def ide_name(self):
        """Gets IDE name."""
        return self._ide_name

    def _get_ide_cmd(self):
        """Compose launch IDE command to run a new process and redirect output.

        Returns:
            A string of launch IDE command.
        """
        return _get_run_ide_cmd(self._installed_path, self.project_abspath)

    def _init_installed_path(self, installed_path):
        """Initialize IDE installed path.

        Args:
            installed_path: the installed path to be checked.
        """
        if installed_path:
            self._installed_path = _get_script_from_input_path(
                installed_path, self._bin_file_name)
        else:
            self._installed_path = self._get_script_from_system()

    def _get_script_from_system(self):
        """Get correct IDE installed path from internal path.

        Returns:
            The sh full path, or None if no IntelliJ version is installed.
        """
        return _get_script_from_internal_path(self._bin_paths, self._ide_name)

    def _get_possible_bin_paths(self):
        """Gets all possible IDE installed paths."""
        return [os.path.join(f, self._bin_file_name) for f in self._bin_folders]


class IdeIntelliJ(IdeBase):
    """Provide basic IntelliJ ops, e.g., launch IDEA, and config IntelliJ.

    Class Attributes:
        _JDK_PATH: The path of JDK in android project.
        _IDE_JDK_TABLE_PATH: The path of JDK table which record JDK info in IDE.
        _JDK_PART_TEMPLATE_PATH: The path of the template of partial JDK table.
        _SYMBOLIC_VERSIONS: A string list of the symbolic link paths of
        IntelliJ.

    For example:
        1. Check if IntelliJ is installed.
        2. Launch an IntelliJ.
        3. Config IntelliJ.
    """

    _JDK_PATH = ''
    _IDE_JDK_TABLE_PATH = ''
    _JDK_PART_TEMPLATE_PATH = ''
    _DEFAULT_ANDROID_SDK_PATH = ''
    _SYMBOLIC_VERSIONS = []

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._ide_name = constant.IDE_INTELLIJ
        self._ls_ce_path = ''
        self._ls_ue_path = ''
        self._init_installed_path(installed_path)

    def apply_optional_config(self):
        """Do IDEA global config action.

        Run code style config, SDK config.
        """
        if not self._installed_path:
            return
        # Skip config action if there's no config folder exists.
        _path_list = self._get_config_root_paths()
        if not _path_list:
            return

        for _config_path in _path_list:
            jdk_file = os.path.join(_config_path, self._IDE_JDK_TABLE_PATH)
            jdk_table = sdk_config.SDKConfig(
                jdk_file, self._JDK_PART_TEMPLATE_PATH, self._JDK_PATH,
                self._DEFAULT_ANDROID_SDK_PATH)
            jdk_table.config_jdk_file()
            jdk_table.gen_enable_debugger_module(self.project_abspath)

    def _get_config_root_paths(self):
        """Get the config root paths from derived class.

        Returns:
            A string list of IDE config paths, return multiple paths if more
            than one path are found, return None if no path is found.
        """
        raise NotImplementedError()

    def _get_config_folder_name(self):
        """Get the config sub folder name from derived class.

        Returns:
            A string of the sub path for the config folder.
        """
        raise NotImplementedError('Method overriding is needed.')

    def _get_preferred_version(self):
        """Get users' preferred IntelliJ version.

        Locates the IntelliJ IDEA launch script path by following rule.

        1. If config file recorded user's preference version, load it.
        2. If config file didn't record, search them form default path if there
           are more than one version, ask user and record it.

        Returns:
            The sh full path, or None if no IntelliJ version is installed.
        """
        ce_paths = _get_intellij_version_path(self._ls_ce_path)
        ue_paths = _get_intellij_version_path(self._ls_ue_path)
        all_versions = self._get_all_versions(ce_paths, ue_paths)
        if len(all_versions) > 1:
            with config.AidegenConfig() as aconf:
                if not self._config_reset and (
                        aconf.preferred_version in all_versions):
                    return aconf.preferred_version
                display_versions = self._merge_symbolic_version(all_versions)
                preferred = _ask_preference(display_versions)
                if preferred:
                    aconf.preferred_version = self._get_real_path(preferred)
                return aconf.preferred_version
        elif all_versions:
            return all_versions[0]
        return None

    @staticmethod
    def _merge_symbolic_version(versions):
        """Merge the duplicate version of symbolic links.

        Stable and beta versions are a symbolic link to a version.
        This function combine two versions to one.
        Ex:
        ['/opt/intellij-ce-stable/bin/idea.sh',
        '/opt/intellij-ce-2019.1/bin/idea.sh'] to
        ['/opt/intellij-ce-stable/bin/idea.sh ->
        /opt/intellij-ce-2019.1/bin/idea.sh',
        '/opt/intellij-ce-2019.1/bin/idea.sh']

        Args:
            versions: A list of all installed versions.

        Returns:
            A list of versions to show for user to select. It may contain
            'symbolic_path/idea.sh -> original_path/idea.sh'.
        """
        display_versions = versions[:]
        for symbolic_version in IdeIntelliJ._SYMBOLIC_VERSIONS:
            if symbolic_version in display_versions and os.path.isfile(
                    symbolic_version):
                real_path = os.path.realpath(symbolic_version)
                for index, path in enumerate(display_versions):
                    if path == symbolic_version:
                        display_versions[index] = ' -> '.join(
                            [display_versions[index], real_path])
                        break
        return display_versions

    @staticmethod
    def _get_real_path(path):
        """ Get real path from merged path.

        Args:
            path: A path string may be merged with symbolic path.
        Returns:
            The real IntelliJ installed path.
        """
        return path.split()[0]

    def _get_script_from_system(self):
        """Get correct IntelliJ installed path from internal path.

        Returns:
            The sh full path, or None if no IntelliJ version is installed.
        """
        found = self._get_preferred_version()
        if found:
            logging.debug('IDE internal installed path: %s.', found)
        return found

    @staticmethod
    def _get_all_versions(cefiles, uefiles):
        """Get all versions of launch script files.

        Args:
            cefiles: CE version launch script paths.
            uefiles: UE version launch script paths.

        Returns:
            A list contains all versions of launch script files.
        """
        all_versions = []
        if cefiles:
            all_versions.extend(cefiles)
        if uefiles:
            all_versions.extend(uefiles)
        return all_versions


class IdeLinuxIntelliJ(IdeIntelliJ):
    """Provide the IDEA behavior implementation for OS Linux.

    Class Attributes:
        _INTELLIJ_RE: Regular expression of IntelliJ installed name in GLinux.

    For example:
        1. Check if IntelliJ is installed.
        2. Launch an IntelliJ.
        3. Config IntelliJ.
    """

    _JDK_PATH = os.path.join(common_util.get_android_root_dir(),
                             'prebuilts/jdk/jdk8/linux-x86')
    # TODO(b/127899277): Preserve a config for jdk version option case.
    _IDE_JDK_TABLE_PATH = 'config/options/jdk.table.xml'
    _JDK_PART_TEMPLATE_PATH = os.path.join(
        common_util.get_aidegen_root_dir(),
        'templates/jdkTable/part.jdk.table.xml')
    _DEFAULT_ANDROID_SDK_PATH = os.path.join(os.getenv('HOME'), 'Android/Sdk')
    IdeIntelliJ._SYMBOLIC_VERSIONS = ['/opt/intellij-ce-stable/bin/idea.sh',
                                      '/opt/intellij-ue-stable/bin/idea.sh',
                                      '/opt/intellij-ce-beta/bin/idea.sh',
                                      '/opt/intellij-ue-beta/bin/idea.sh']
    _INTELLIJ_RE = re.compile(r'intellij-(ce|ue)-')

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._bin_file_name = 'idea.sh'
        self._bin_folders = ['/opt/intellij-*/bin']
        self._ls_ce_path = os.path.join('/opt/intellij-ce-*/bin',
                                        self._bin_file_name)
        self._ls_ue_path = os.path.join('/opt/intellij-ue-*/bin',
                                        self._bin_file_name)
        self._init_installed_path(installed_path)

    def _get_config_root_paths(self):
        """To collect the global config folder paths of IDEA as a string list.

        The config folder of IntelliJ IDEA is under the user's home directory,
        .IdeaIC20xx.x and .IntelliJIdea20xx.x are folder names for different
        versions.

        Returns:
            A string list for IDE config root paths, and return None for failed
            to found case.
        """
        if not self._installed_path:
            return None

        _config_folders = []
        _config_folder = ''
        if IdeLinuxIntelliJ._INTELLIJ_RE.search(self._installed_path):
            # GLinux case.
            if self._installed_path in IdeIntelliJ._SYMBOLIC_VERSIONS:
                _path_data = os.path.realpath(self._installed_path).split('-')
            else:
                _path_data = self._installed_path.split('-')
            _ide_version = _path_data[2].split(os.sep)[0]
            if _path_data[1] == 'ce':
                _config_folder = ''.join(['.IdeaIC', _ide_version])
            else:
                _config_folder = ''.join(['.IntelliJIdea', _ide_version])

            _config_folders.append(
                os.path.join(os.getenv('HOME'), _config_folder))
        else:
            # TODO(b/123459239): For the case that the user provides the IDEA
            # binary path, we now collect all possible IDEA config root paths.
            _config_folders = glob.glob(
                os.path.join(os.getenv('HOME'), '.IdeaI?20*'))
            _config_folders.extend(
                glob.glob(os.path.join(os.getenv('HOME'), '.IntelliJIdea20*')))
            logging.info('The config path list: %s.', _config_folders)

        return _config_folders

    def _get_config_folder_name(self):
        """A interface used to provide the config sub folder name.

        Returns:
            A sub path string of the config folder.
        """
        return os.path.join('config', 'codestyles')


class IdeMacIntelliJ(IdeIntelliJ):
    """Provide the IDEA behavior implementation for OS Mac.

    For example:
        1. Check if IntelliJ is installed.
        2. Launch an IntelliJ.
        3. Config IntelliJ.
    """

    _JDK_PATH = os.path.join(common_util.get_android_root_dir(),
                             'prebuilts/jdk/jdk8/darwin-x86')
    _IDE_JDK_TABLE_PATH = 'options/jdk.table.xml'
    _JDK_PART_TEMPLATE_PATH = os.path.join(
        common_util.get_aidegen_root_dir(),
        'templates/jdkTable/part.mac.jdk.table.xml')
    _DEFAULT_ANDROID_SDK_PATH = os.path.join(
        os.getenv('HOME'), 'Library/Android/sdk')

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._bin_file_name = 'idea'
        self._bin_folders = ['/Applications/IntelliJ IDEA.app/Contents/MacOS']
        self._bin_paths = self._get_possible_bin_paths()
        self._ls_ce_path = os.path.join(
            '/Applications/IntelliJ IDEA CE.app/Contents/MacOS',
            self._bin_file_name)
        self._ls_ue_path = os.path.join(
            '/Applications/IntelliJ IDEA.app/Contents/MacOS',
            self._bin_file_name)
        self._init_installed_path(installed_path)

    def _get_config_root_paths(self):
        """To collect the global config folder paths of IDEA as a string list.

        Returns:
            A string list for IDE config root paths, and return None for failed
            to found case.
        """
        if not self._installed_path:
            return None

        _config_folders = []
        if 'IntelliJ' in self._installed_path:
            _config_folders = glob.glob(
                os.path.join(
                    os.getenv('HOME'), 'Library/Preferences/IdeaI?20*'))
            _config_folders.extend(
                glob.glob(
                    os.path.join(
                        os.getenv('HOME'),
                        'Library/Preferences/IntelliJIdea20*')))
        return _config_folders

    def _get_config_folder_name(self):
        """A interface used to provide the config sub folder name.

        Returns:
            A sub path string of the config folder.
        """
        return 'codeStyles'


class IdeStudio(IdeBase):
    """Class offers a set of Android Studio launching utilities.

    For example:
        1. Check if Android Studio is installed.
        2. Launch an Android Studio.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._ide_name = constant.IDE_ANDROID_STUDIO


class IdeLinuxStudio(IdeStudio):
    """Class offers a set of Android Studio launching utilities for OS Linux.

    For example:
        1. Check if Android Studio is installed.
        2. Launch an Android Studio.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._bin_file_name = 'studio.sh'
        self._bin_folders = ['/opt/android-*/bin']
        self._bin_paths = self._get_possible_bin_paths()
        self._init_installed_path(installed_path)


class IdeMacStudio(IdeStudio):
    """Class offers a set of Android Studio launching utilities for OS Mac.

    For example:
        1. Check if Android Studio is installed.
        2. Launch an Android Studio.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._bin_file_name = 'studio'
        self._bin_folders = ['/Applications/Android Studio.app/Contents/MacOS']
        self._bin_paths = self._get_possible_bin_paths()
        self._init_installed_path(installed_path)


class IdeEclipse(IdeBase):
    """Class offers a set of Eclipse launching utilities.

    Attributes:
        cmd: A list of the build command.

    For example:
        1. Check if Eclipse is installed.
        2. Launch an Eclipse.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._ide_name = constant.IDE_ECLIPSE
        self._bin_file_name = 'eclipse'
        self.cmd = []

    def _get_script_from_system(self):
        """Get correct IDE installed path from internal path.

        Remove any file with extension, the filename should be like, 'eclipse',
        'eclipse47' and so on, check if the file is executable and filter out
        file such as 'eclipse.ini'.

        Returns:
            The sh full path, or None if no IntelliJ version is installed.
        """
        for ide_path in self._bin_paths:
            # The binary name of Eclipse could be eclipse47, eclipse49,
            # eclipse47_testing or eclipse49_testing. So finding the matched
            # binary by /path/to/ide/eclipse*.
            ls_output = glob.glob(ide_path + '*', recursive=True)
            if ls_output:
                ls_output = sorted(ls_output)
                match_eclipses = []
                for path in ls_output:
                    if os.access(path, os.X_OK):
                        match_eclipses.append(path)
                if match_eclipses:
                    match_eclipses = sorted(match_eclipses)
                    logging.debug('Result for checking %s after sort: %s.',
                                  self._ide_name, match_eclipses[0])
                    return match_eclipses[0]
        logging.error('No %s installed.', self._ide_name)
        return None

    def _get_ide_cmd(self):
        """Compose launch IDE command to run a new process and redirect output.

        AIDEGen will create a default workspace
        ~/Documents/AIDEGen_Eclipse_workspace for users if they agree to do
        that. Also, we could not import the default project through the command
        line so remove the project path argument.

        Returns:
            A string of launch IDE command.
        """
        if (os.path.exists(os.path.expanduser(_ECLIPSE_WS))
                or str(input(_ALERT_CREATE_WS)).lower() == 'y'):
            self.cmd.extend(['-data', _ECLIPSE_WS])
        self.cmd.extend([_IGNORE_STD_OUT_ERR_CMD, '&'])
        return ' '.join(self.cmd)


class IdeLinuxEclipse(IdeEclipse):
    """Class offers a set of Eclipse launching utilities for OS Linux.

    For example:
        1. Check if Eclipse is installed.
        2. Launch an Eclipse.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._bin_folders = ['/opt/eclipse*', '/usr/bin/']
        self._bin_paths = self._get_possible_bin_paths()
        self._init_installed_path(installed_path)
        self.cmd = [_NOHUP, self._installed_path.replace(' ', r'\ ')]


class IdeMacEclipse(IdeEclipse):
    """Class offers a set of Eclipse launching utilities for OS Mac.

    For example:
        1. Check if Eclipse is installed.
        2. Launch an Eclipse.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._bin_file_name = 'eclipse'
        self._bin_folders = [os.path.expanduser('~/eclipse/**')]
        self._bin_paths = self._get_possible_bin_paths()
        self._init_installed_path(installed_path)
        self.cmd = [self._installed_path.replace(' ', r'\ ')]


class IdeCLion(IdeBase):
    """Class offers a set of CLion launching utilities.

    For example:
        1. Check if CLion is installed.
        2. Launch an CLion.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._ide_name = constant.IDE_CLION


class IdeLinuxCLion(IdeCLion):
    """Class offers a set of CLion launching utilities for OS Linux.

    For example:
        1. Check if CLion is installed.
        2. Launch an CLion.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._bin_file_name = 'clion.sh'
        self._bin_folders = ['/opt/clion-2*/bin']
        self._bin_paths = self._get_possible_bin_paths()
        self._init_installed_path(installed_path)


class IdeMacCLion(IdeCLion):
    """Class offers a set of Android Studio launching utilities for OS Mac.

    For example:
        1. Check if Android Studio is installed.
        2. Launch an Android Studio.
    """

    def __init__(self, installed_path=None, config_reset=False):
        super().__init__(installed_path, config_reset)
        self._bin_file_name = 'clion'
        self._bin_folders = ['/Applications/CLion.app/Contents/MacOS/CLion']
        self._bin_paths = self._get_possible_bin_paths()
        self._init_installed_path(installed_path)


def _get_script_from_internal_path(ide_paths, ide_name):
    """Get the studio.sh script path from internal path.

    Args:
        ide_paths: A list of IDE installed paths to be checked.
        ide_name: The IDE name.

    Returns:
        The IDE full path or None if no Android Studio or Eclipse is installed.
    """
    for ide_path in ide_paths:
        ls_output = glob.glob(ide_path, recursive=True)
        ls_output = sorted(ls_output)
        if ls_output:
            logging.debug('Result for checking %s after sort: %s.', ide_name,
                          ls_output[0])
            return ls_output[0]
    logging.error('No %s installed.', ide_name)
    return None


def _run_ide_sh(run_sh_cmd, project_path):
    """Run IDE launching script with an IntelliJ project path as argument.

    Args:
        run_sh_cmd: The command to launch IDE.
        project_path: The path of IntelliJ IDEA project content.
    """
    assert run_sh_cmd, 'No suitable IDE installed.'
    logging.debug('Run command: "%s" to launch project.', run_sh_cmd)
    try:
        subprocess.check_call(run_sh_cmd, shell=True)
    except subprocess.CalledProcessError as err:
        logging.error('Launch project path %s failed with error: %s.',
                      project_path, err)


def _walk_tree_find_ide_exe_file(top, ide_script_name):
    """Recursively descend the directory tree rooted at top and filter out the
       IDE executable script we need.

    Args:
        top: the tree root to be checked.
        ide_script_name: IDE file name such i.e. IdeIntelliJ._INTELLIJ_EXE_FILE.

    Returns:
        the IDE executable script file(s) found.
    """
    logging.info('Searching IDE script %s in path: %s.', ide_script_name, top)
    for root, _, files in os.walk(top):
        logging.debug('Search all files under %s to get %s, %s.', top, root,
                      files)
        for file_ in fnmatch.filter(files, ide_script_name):
            exe_file = os.path.join(root, file_)
            if os.access(exe_file, os.X_OK):
                logging.debug('Use file name filter to find %s in path %s.',
                              file_, exe_file)
                yield exe_file


def _get_run_ide_cmd(sh_path, project_file):
    """Get the command to launch IDE.

    Args:
        sh_path: The idea.sh path where IDE is installed.
        project_file: The path of IntelliJ IDEA project file.

    Returns:
        A string: The IDE launching command.
    """
    # In command usage, the space ' ' should be '\ ' for correctness.
    return ' '.join([
        _NOHUP,
        sh_path.replace(' ', r'\ '), project_file, _IGNORE_STD_OUT_ERR_CMD, '&'
    ])


def _get_script_from_file_path(input_path, ide_file_name):
    """Get IDE executable script file from input file path.

    Args:
        input_path: the file path to be checked.
        ide_file_name: the IDE executable script file name.

    Returns:
        An IDE executable script path if exists otherwise None.
    """
    if os.path.basename(input_path).startswith(ide_file_name):
        files_found = glob.glob(input_path)
        if files_found:
            return sorted(files_found)[0]
    return None


def _get_script_from_dir_path(input_path, ide_file_name):
    """Get an IDE executable script file from input directory path.

    Args:
        input_path: the directory to be searched.
        ide_file_name: the IDE executable script file name.

    Returns:
        An IDE executable script path if exists otherwise None.
    """
    logging.debug('Call _get_script_from_dir_path with %s, and %s', input_path,
                  ide_file_name)
    files_found = list(_walk_tree_find_ide_exe_file(input_path,
                                                    ide_file_name + '*'))
    if files_found:
        return sorted(files_found)[0]
    return None


def _launch_ide(project_path, run_ide_cmd, ide_name):
    """Launches relative IDE by opening the passed project file.

    Args:
        project_path: The full path of the IDE project content.
        run_ide_cmd: The command to launch IDE.
        ide_name: the IDE name is to be launched.
    """
    assert project_path, 'Empty content path is not allowed.'
    if ide_name == constant.IDE_ECLIPSE:
        logging.info('Launch %s with workspace: %s.', ide_name, _ECLIPSE_WS)
    else:
        logging.info('Launch %s for project content path: %s.', ide_name,
                     project_path)
    _run_ide_sh(run_ide_cmd, project_path)


def _is_intellij_project(project_path):
    """Checks if the path passed in is an IntelliJ project content.

    Args:
        project_path: The full path of IDEA project content, which contains
        .idea folder and .iml file(s).

    Returns:
        True if project_path is an IntelliJ project, False otherwise.
    """
    if not os.path.isfile(project_path):
        return os.path.isdir(project_path) and os.path.isdir(
            os.path.join(project_path, _IDEA_FOLDER))

    _, ext = os.path.splitext(os.path.basename(project_path))
    if ext and _IML_EXTENSION == ext.lower():
        path = os.path.dirname(project_path)
        logging.debug('Extracted path is: %s.', path)
        return os.path.isdir(os.path.join(path, _IDEA_FOLDER))
    return False


def _get_script_from_input_path(input_path, ide_file_name):
    """Get correct IntelliJ executable script path from input path.

    1. If input_path is a file, check if it is an IDE executable script file.
    2. It input_path is a directory, search if it contains IDE executable script
       file(s).

    Args:
        input_path: input path to be checked if it's an IDE executable
                    script.
        ide_file_name: the IDE executable script file name.

    Returns:
        IDE executable file(s) if exists otherwise None.
    """
    if not input_path:
        return None
    ide_path = ''
    if os.path.isfile(input_path):
        ide_path = _get_script_from_file_path(input_path, ide_file_name)
    if os.path.isdir(input_path):
        ide_path = _get_script_from_dir_path(input_path, ide_file_name)
    if ide_path:
        logging.debug('IDE installed path from user input: %s.', ide_path)
        return ide_path
    return None


def _get_intellij_version_path(version_path):
    """Locates the IntelliJ IDEA launch script path by version.

    Args:
        version_path: IntelliJ CE or UE version launch script path.

    Returns:
        The sh full path, or None if no such IntelliJ version is installed.
    """
    ls_output = glob.glob(version_path, recursive=True)
    if not ls_output:
        return None
    ls_output = sorted(ls_output, reverse=True)
    logging.debug('Result for checking IntelliJ path %s after sorting:%s.',
                  version_path, ls_output)
    return ls_output


def _ask_preference(all_versions):
    """Ask users which version they prefer.

    Args:
        all_versions: A list of all CE and UE version launch script paths.

    Returns:
        An users selected version.
    """
    options = []
    for i, sfile in enumerate(all_versions, 1):
        options.append('\t{}. {}'.format(i, sfile))
    query = ('You installed {} versions of IntelliJ:\n{}\nPlease select '
             'one.\t').format(len(all_versions), '\n'.join(options))
    return _select_intellij_version(query, all_versions)


def _select_intellij_version(query, all_versions):
    """Select one from different IntelliJ versions users installed.

    Args:
        query: The query message.
        all_versions: A list of all CE and UE version launch script paths.
    """
    all_numbers = []
    for i in range(len(all_versions)):
        all_numbers.append(str(i + 1))
    input_data = input(query)
    while input_data not in all_numbers:
        input_data = input('Please select a number:\t')
    return all_versions[int(input_data) - 1]


def _get_ide(installed_path=None, ide='j', config_reset=False, is_mac=False):
    """Get IDE to be launched according to the ide input and OS type.

    Args:
        installed_path: The IDE installed path to be checked.
        ide: A key character of IDE to be launched. Default ide='j' is to
            launch IntelliJ.
        config_reset: A boolean, if true reset configuration data.

    Returns:
        A corresponding IDE instance.
    """
    if is_mac:
        return _get_mac_ide(installed_path, ide, config_reset)
    return _get_linux_ide(installed_path, ide, config_reset)


def _get_mac_ide(installed_path=None, ide='j', config_reset=False):
    """Get IDE to be launched according to the ide input for OS Mac.

    Args:
        installed_path: The IDE installed path to be checked.
        ide: A key character of IDE to be launched. Default ide='j' is to
            launch IntelliJ.
        config_reset: A boolean, if true reset configuration data.

    Returns:
        A corresponding IDE instance.
    """
    if ide == 'e':
        return IdeMacEclipse(installed_path)
    if ide == 's':
        return IdeMacStudio(installed_path)
    if ide == 'c':
        return IdeMacCLion(installed_path)
    return IdeMacIntelliJ(installed_path, config_reset)


def _get_linux_ide(installed_path=None, ide='j', config_reset=False):
    """Get IDE to be launched according to the ide input for OS Linux.

    Args:
        installed_path: The IDE installed path to be checked.
        ide: A key character of IDE to be launched. Default ide='j' is to
            launch IntelliJ.
        config_reset: A boolean, if true reset configuration data.

    Returns:
        A corresponding IDE instance.
    """
    if ide == 'e':
        return IdeLinuxEclipse(installed_path)
    if ide == 's':
        return IdeLinuxStudio(installed_path)
    if ide == 'c':
        return IdeLinuxCLion(installed_path)
    return IdeLinuxIntelliJ(installed_path, config_reset)
