import errno
import os
import re

from vee.utils import makedirs, style
import vee.vendor.virtualenv as virtualenv


IGNORE_DIRS = frozenset(('.git', '.svn'))
IGNORE_FILES = frozenset(('.DS_Store', ))


class Environment(object):

    def __init__(self, name, home):
        self.home = home
        if name.startswith('/'):
            self.path = name
            self.name = os.path.basename(name)
        else:
            self.name = name
            self.path = home.abspath('environments', name)
        self._db_id = None


    def create_if_not_exists(self):
        python = os.path.join(self.path, 'bin', 'python')
        if not os.path.exists(python):
            makedirs(self.path)
            print style('Creating Python virtualenv', 'blue', bold=True), style(self.path, bold=True)
            virtualenv.create_environment(self.path, no_setuptools=True, no_pip=True)

    def db_id(self):
        if self._db_id is None:
            cur = self.home.db.cursor()
            row = cur.execute('SELECT * FROM environments WHERE path = ?', [self.path]).fetchone()
            if row:
                self._db_id = row['id']
            else:
                cur.execute('INSERT INTO environments (name, path) VALUES (?, ?)', [
                    self.name, self.path,
                ])
                self._db_id = cur.lastrowid
        return self._db_id

    def link_directory(self, dir_to_link):
        
        self.create_if_not_exists()

        # TODO: Be like Homebrew, and be smarter about what we link, and what
        # we copy.

        for old_dir_path, dir_names, file_names in os.walk(dir_to_link):
            
            rel_dir_path = os.path.relpath(old_dir_path, dir_to_link)
            new_dir_path = os.path.abspath(os.path.join(self.path, rel_dir_path))

            # Ignore AND skip these directories.
            dir_names[:] = [x for x in dir_names if x not in IGNORE_DIRS]
            for dir_name in dir_names:
                makedirs(os.path.join(new_dir_path, dir_name))

            for file_name in file_names:
                if file_name in IGNORE_FILES:
                    continue
                try:
                    os.symlink(
                        os.path.join(old_dir_path, file_name),
                        os.path.join(new_dir_path, file_name),
                    )
                except OSError as e:
                    # TODO: have a vee-link-history.txt in each environment
                    # so that we can quickly check what is already linked there.
                    if e.errno != errno.EEXIST:
                        raise


@@ -1456,16 +1456,75 @@
 ists()%0A%0A
+        python = os.path.join(self.path, 'bin', 'python')%0A%0A
         
@@ -2194,16 +2194,17 @@
 ontinue%0A
+%0A
         
@@ -2215,51 +2215,122 @@
     
-try:%0A                    os.symlink(%0A      
+old_path = os.path.join(old_dir_path, file_name)%0A                new_path = os.path.join(new_dir_path, file_name)%0A
     
@@ -2333,33 +2333,42 @@
                 
- 
+rel_path =
  os.path.join(ol
@@ -2357,35 +2357,35 @@
  = os.path.join(
-old
+rel
 _dir_path, file_
@@ -2381,33 +2381,32 @@
 path, file_name)
-,
 %0A               
@@ -2406,24 +2406,26 @@
         
+%0A 
         
 os.path.
@@ -2420,67 +2420,614 @@
     
-os.path.join(new_dir_path, file_name),%0A                    
+       # If it starts with the Python shebang, rewrite it.%0A                with open(old_path, 'rb') as old_fh:%0A                    shebang = old_fh.readline()%0A                    if re.match(r'%5E#!%5CS*python', shebang):%0A                        print 'Rewriting shebang of', rel_path%0A                        with open(new_path, 'wb') as new_fh:%0A                            new_fh.write('#!%25s%5Cn' %25 python)%0A                            new_fh.writelines(old_fh)%0A                            continue%0A%0A                # Symlink it into place.%0A                try:%0A                    os.symlink(old_path, new_path
 )%0A  

Rewrite shebangs to point at the virtualenv