import os
import subprocess

from nose.tools import istest, assert_equal

from whack.common import WHACK_ROOT
from whack.deployer import PackageDeployer
from whack.tempdir import create_temporary_dir
from whack.files import write_file, mkdir_p


@istest
def run_script_in_installation_mounts_whack_root_before_running_command():
    with create_temporary_dir() as package_dir, create_temporary_dir() as install_dir:
        _write_files(package_dir, [
            FileDescription("message", "Hello there"),
            FileDescription("bin/hello", "#!/bin/sh\ncat {0}/message".format(WHACK_ROOT), 0755),
        ])
        deployer = PackageDeployer()
        deployer.deploy(package_dir, install_dir)
        
        command = [os.path.join(install_dir, "run"), "hello"]
        output = subprocess.check_output(command)
        assert_equal("Hello there", output)


@istest
def placing_executables_under_dot_bin_creates_directly_executable_files_under_bin():
    with create_temporary_dir() as package_dir, create_temporary_dir() as install_dir:
        _write_files(package_dir, [
            FileDescription("message", "Hello there"),
            FileDescription(".bin/hello", "#!/bin/sh\ncat {0}/message".format(WHACK_ROOT), 0755),
        ])
        deployer = PackageDeployer()
        deployer.deploy(package_dir, install_dir)
        
        command = [os.path.join(install_dir, "bin/hello")]
        output = subprocess.check_output(command)
        assert_equal("Hello there", output)


@istest
def files_already_under_bin_are_not_replaced():
    with create_temporary_dir() as package_dir, create_temporary_dir() as install_dir:
        _write_files(package_dir, [
            FileDescription("bin/hello", "#!/bin/sh\necho Hello from bin", 0755),
            FileDescription(".bin/hello", "#!/bin/sh\necho Hello from .bin", 0755),
        ])
        deployer = PackageDeployer()
        deployer.deploy(package_dir, install_dir)
        
        command = [os.path.join(install_dir, "bin/hello")]
        output = subprocess.check_output(command)
        assert_equal("Hello from bin\n", output)


def _write_files(root_dir, file_descriptions):
    for file_description in file_descriptions:
        path = os.path.join(root_dir, file_description.path)
        mkdir_p(os.path.dirname(path))
        write_file(path, file_description.contents)
        os.chmod(path, file_description.permissions)
    

class FileDescription(object):
    def __init__(self, path, contents, permissions=0644):
        self.path = path
        self.contents = contents
        self.permissions = permissions

@@ -504,37 +504,44 @@
 %22),%0A            
-FileD
+_sh_script_d
 escription(%22bin/
@@ -545,35 +545,24 @@
 in/hello%22, %22
-#!/bin/sh%5Cn
 cat %7B0%7D/mess
@@ -576,38 +576,32 @@
 rmat(WHACK_ROOT)
-, 0755
 ),%0A        %5D)%0A  
@@ -1127,37 +1127,44 @@
 %22),%0A            
-FileD
+_sh_script_d
 escription(%22.bin
@@ -1173,27 +1173,16 @@
 ello%22, %22
-#!/bin/sh%5Cn
 cat %7B0%7D/
@@ -1208,22 +1208,16 @@
 CK_ROOT)
-, 0755
 ),%0A     
@@ -1656,37 +1656,44 @@
 , %5B%0A            
-FileD
+_sh_script_d
 escription(%22bin/
@@ -1697,35 +1697,24 @@
 in/hello%22, %22
-#!/bin/sh%5Cn
 echo Hello f
@@ -1717,30 +1717,24 @@
 lo from bin%22
-, 0755
 ),%0A         
@@ -1728,37 +1728,44 @@
 %22),%0A            
-FileD
+_sh_script_d
 escription(%22.bin
@@ -1778,19 +1778,8 @@
 %22, %22
-#!/bin/sh%5Cn
 echo
@@ -1799,14 +1799,8 @@
 bin%22
-, 0755
 ),%0A 
@@ -2364,20 +2364,136 @@
 ssions)%0A
-    
+%0A%0Adef _sh_script_description(path, contents):%0A    return FileDescription(path, %22#!/bin/sh%5Cn%7B0%7D%22.format(contents), 0755)%0A
 %0A%0Aclass 

Remove duplicated test code for creating scripts