#!/usr/bin/env python
# Copyright (c) 2015, 2017 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 traceback

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 is treated as an absolute path. You can use a relative path, but it will be expanded
      to absolute for storage. Upon fetch, you can use the same relative path, so long as it resolves
      to the same absolute location. It is safest to just specify an absolute path yourself.

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

if __name__ == '__main__':
    args = sys.argv[1:]

    if '--help' in args or len(args) == 0:
        printUsage()
        sys.exit(1)

    password = None
    isPromptPassword = False
    isPreserveAttributes = True
    configFilename = None

    for arg in args[:]:
        if arg == '--password':

            args.remove('--password')
            isPromptPassword = True

        elif arg.startswith('--password-file='):

            isPromptPassword = False
            args.remove(arg)
            passwordFilename = arg[len('--password-file='):]
            password = readPasswordFromFilename(passwordFilename)

        elif arg == '--no-preserve':

            args.remove('--no-preserve')
            isPreserveAttributes = False

        elif arg.startswith('--config='):

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

    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(args)
    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 = args[0]
    filename = args[1]
    localFilename = args[2]

    if not filename.startswith('/'):
        filename = os.path.realpath(filename)

    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:
        exc_info = sys.exc_info()
        sys.stderr.write(str(e) + '\n')
        traceback.print_exception(*exc_info)

        sys.exit(4)

