import os
from os.path import join
import shutil


class PathInfo(object):
    '''
    The originating file path would look something like this: 

        /home/username/blog-site/contents/blog/posts/post_name.md

    PathInfo only deals with the relative nature of the files path
    and contains the following values:

        # input paths
        root  => /home/user/blog-site
        dir_  => /blog/posts
        base  => post_name
        ext   => .md

        # generated paths
        rel_path   => /blog/posts/post_name.md 
        full_path  => /home/user/blog-site/blog/posts/post_name.md
        full_dir   => /home/user/blog-site/blog/posts

    '''
    def __init__(self, root, dir_, base, ext=None):
        self.root = root
        self.dir_ = dir_
        # split the ext from base if it has one
        base_name, base_ext = os.path.splitext(base)
        self.base = base_name 
        self.ext = ext or base_ext
        self.rel_path = join('/', self.dir_.strip('/'), self.base + self.ext)
        self.full_path = join(self.root, self.dir_.strip('/'), self.base + self.ext)
        self.full_dir = os.path.dirname(self.full_path)

    def copy_as(self, **kwargs):
        root = kwargs.get('root', self.root)
        dir_ = kwargs.get('dir', self.dir_)
        base = kwargs.get('base', self.base)
        ext = kwargs.get('ext', self.ext)
        return PathInfo(root, dir_, base, ext) 

    def __str__(self):
        return self.rel_path

    def __repr__(self):
        return '<FileInfo {0}>'.format(self)


def copy_dir(src_dir, dst_dir):
    # collect the source directory path info
    if not os.path.exists(src_dir) or not os.path.exists(dst_dir):
        raise Exception('The source or destination directory does not exist.')

    src_paths = [] 
    for root, dirs, files in os.walk(src_dir):
        relpath = os.path.relpath(root, src_dir)
        if relpath == ".":
            relpath = ""
        for file_name in files:
            src_paths.append(PathInfo(src_dir, relpath, file_name))

    # copy and transform our paths with a new root
    for src in src_paths:
        dst = src.copy_as(root=dst_dir) 
        if not os.path.exists(dst.full_dir):
            os.makedirs(dst.full_dir)
        shutil.copy(src.full_path, dst.full_path)


def test():
    print ''
    print 'Make original paths...'
    print '-----------------------'
    
    path_1 = PathInfo('/home/freddie/blog/contents', '/blog', 'posts')
    path_2 = PathInfo('/home/freddie/blog/contents', '/blog/posts', 'on_prototypes.markdown')

    print 'relative paths:'
    print path_1
    print path_2

    print 'full paths:'
    print path_1.full_path
    print path_2.full_path

    print ''
    print 'Make a verbatim copy...'
    print '-----------------------'
    path_1a = path_1.copy_as()
    path_2a = path_2.copy_as()

    print 'relative paths:'
    print path_1a
    print path_2a

    print 'full paths:'
    print path_1a.full_path
    print path_2a.full_path

    print ''
    print 'Make a copy and transform...'
    print '----------------------------'
    path_1b = path_1.copy_as(root='/home/freddie/blog/build')
    path_2b = path_2.copy_as(root='/home/freddie/blog/build', ext='.html')

    print 'relative paths:'
    print path_1b
    print path_2b

    print 'full paths:'
    print path_1b.full_path
    print path_2b.full_path

if __name__ == '__main__':
    import sys
    args = sys.argv[1:]
    if len(args) == 2:
        copy_dir(*args)
    else:
        test()
