#!/usr/bin/env python
# Copyright (c) 2015 Tim Savannah GPLv3 + attribution clause. See LICENSE for more information.
# 
#  This file contains the application to retrieve files stored in NetFetch

# vim: ts=4 sw=4 expandtab

import os
import sys

import getpass

from NetFetch import NetFetchFile, NoSuchNetFetchFile, InvalidPasswordException, setRedisConnectionParams
from NetFetch.config import getRedisConnectionParams
from NetFetch.client_utils import readPasswordFromFilename, findDefaultConfigFilename


def printUsage():
    sys.stderr.write('''Usage: netFetchGet (options) [hostname] [filename] [output filename]
  Downloads a file uploaded from hostname, given an absolute filename.
  If "output filename" is "--", output will be to stdout. 

    Options:

      --password                  Prompts for password. If file is encrypted, a password must be provided.
      --password-file=fname       Read password from a given filename instead of tty. Implies --password.
      
      --no-preserve               Do not apply stored attributes (owner/group/mode)

      --config=/path/config.cfg   Use provided config for redis. Default is to look in ~/.netfetch.cfg then /etc/netfetch.cfg

    Provided filename must be an absolute path.

 Example: netFetchGet filestore01 /Data/myfile.db
''')

if __name__ == '__main__':
    args = set(sys.argv[1:])
    if '--help' in args or len(args) == 0:
        printUsage()
        sys.exit(1)

    password = None
    isPromptPassword = False
    isPreserveAttributes = True

    if '--password' in args:
        sys.argv.remove('--password')
        args.remove('--password')
        isPromptPassword = True
    
    for arg in args:
        if arg.startswith('--password-file='):
            isPromptPassword = False
            sys.argv.remove(arg)
            args.remove(arg)
            passwordFilename = arg[len('--password-file='):]
            password = readPasswordFromFilename(passwordFilename)
            break

    if '--no-preserve' in args:
        sys.argv.remove('--no-preserve')
        args.remove('--no-preserve')
        isPreserveAttributes = False

    configFilename = None

    for arg in args:
        if arg.startswith('--config='):
            configFilename = arg[len('--config='):]
            sys.argv.remove(arg)
            if not os.path.isfile(configFilename):
                sys.stderr.write('Cannot find provided config file, "%s"\n' %(configFilename,))
                sys.exit(5)
            break

    if not configFilename:
        configFilename = findDefaultConfigFilename()
        if not configFilename:
            sys.stderr.write('No config file provided, and none found in default locations of $HOME/.netfetch.cfg or /etc/netfetch.cfg. Please provide one with --config=/path/to/netfetch.cfg\n')
            sys.exit(5)


    if not os.path.isfile(configFilename):
        sys.stderr.write('Config file %s does not exist! Specify an alternative with --config=/path/to/file.cfg?\n' %(configFilename,))
        sys.exit(5)

    numArgs = len(sys.argv) - 1
    if numArgs != 3:
        if numArgs < 2:
            sys.stderr.write('Too few arguments.\n\n')
            printUsage()
        else:
            sys.stderr.write('Too many arguments.\n\n')
            printUsage()
        sys.exit(1)


    try:
        redisConnectionParams = getRedisConnectionParams(configFilename)
    except Exception as e:
        sys.stderr.write('Error parsing config file: %s\n' %(configFilename,))
        sys.exit(5)

    setRedisConnectionParams(redisConnectionParams)


    
    hostname = sys.argv[1]
    filename = sys.argv[2]
    localFilename = sys.argv[3]

    if isPromptPassword:
        password = getpass.getpass()

    try:
        if localFilename == '--':
            res = NetFetchFile.downloadToStr(hostname, filename, password)
            sys.stdout.write(res.decode('utf-8'))
        else:
            NetFetchFile.downloadToLocal(hostname, filename, password, localFilename, isPreserveAttributes)
    except NoSuchNetFetchFile as e:
        sys.stderr.write(str(e) + '\n')
        sys.exit(2)
    except InvalidPasswordException as e:
        sys.stderr.write(str(e) + '\n')
        sys.exit(3)
    except Exception as e:
        sys.stderr.write(str(e) + '\n')
        sys.exit(4)

