# Licensed to the StackStorm, Inc ('StackStorm') under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

import os
import pwd
import six
import sys
import traceback
import tempfile

from fabric.api import (put, run, sudo)
from fabric.context_managers import shell_env
from fabric.context_managers import settings
from fabric.tasks import WrappedCallableTask

from st2common import log as logging
from st2common.util.shell import quote_unix
from st2common.constants.action import LIBS_DIR as ACTION_LIBS_DIR
from st2common.exceptions.fabricrunner import FabricExecutionFailureException
import st2common.util.jsonify as jsonify

__all__ = [
    'ShellCommandAction',
    'ShellScriptAction',
    'RemoteAction',
    'RemoteScriptAction',
    'ParamikoSSHCommandAction',
    'FabricRemoteAction',
    'FabricRemoteScriptAction'
]

LOG = logging.getLogger(__name__)

LOGGED_USER_USERNAME = pwd.getpwuid(os.getuid())[0]


class ShellCommandAction(object):
    def __init__(self, name, action_exec_id, command, user, env_vars=None, sudo=False,
                 timeout=None, cwd=None):
        self.name = name
        self.action_exec_id = action_exec_id
        self.command = command
        self.env_vars = env_vars or {}
        self.user = user
        self.sudo = sudo
        self.timeout = timeout
        self.cwd = cwd

    def get_full_command_string(self):
        # Note: We pass -E to sudo because we want to preserve user provided
        # environment variables
        if self.sudo:
            command = quote_unix(self.command)
            command = 'sudo -E -- bash -c %s' % (command)
        else:
            if self.user and self.user != LOGGED_USER_USERNAME:
                # Need to use sudo to run as a different user
                user = quote_unix(self.user)
                command = quote_unix(self.command)
                command = 'sudo -E -u %s -- bash -c %s' % (user, command)