# -*- coding: utf-8 -*-
import logging
import os
import sys
import time
from datetime import datetime, timedelta
from dateutil import parser
from urlparse import urljoin

import pytz
import requests

from satnogsclient import settings
from satnogsclient.observer.observer import Observer
from satnogsclient.receiver import SignalReceiver
from satnogsclient.scheduler import scheduler


logger = logging.getLogger('satnogsclient')


def spawn_observer(*args, **kwargs):
    obj = kwargs.pop('obj')
    tle = {
        'tle0': obj['tle0'],
        'tle1': obj['tle1'],
        'tle2': obj['tle2']
    }
    end = parser.parse(obj['end'])

    observer = Observer()
    observer.location = {
        'lon': settings.GROUND_STATION_LON,
        'lat': settings.GROUND_STATION_LAT,
        'elev': settings.GROUND_STATION_ELEV
    }

    setup_kwargs = {
        'observation_id': obj['id'],
        'tle': tle,
        'observation_end': end,
        'frequency': obj['frequency']
    }

    logger.debug('Observer args: {0}'.format(setup_kwargs))
    setup = observer.setup(**setup_kwargs)

    if setup:
        logger.info('Spawning observer worker.')
        observer.observe()
    else:
        raise RuntimeError('Error in observer setup.')


def spawn_receiver(*args, **kwargs):
    obj = kwargs.pop('obj')
    logger.debug('Receiver args: {0}'.format(obj))
    receiver = SignalReceiver(obj['id'], obj['frequency'])
    logger.info('Spawning receiver worker.')
    receiver.run()
    end = parser.parse(obj['end'])

    while True:
        if datetime.now(pytz.utc) < end:
            time.sleep(1)
        else:
            receiver.stop()
            sys.exit()


def post_data():
    """PUT observation data back to Network API."""
    base_url = urljoin(settings.NETWORK_API_URL, 'data/')
    headers = {'Authorization': 'Token {0}'.format(settings.API_TOKEN)}

    for root, dirs, files in os.walk(settings.OUTPUT_PATH):
        for f in files:
            observation_id = f.split('_')[1]
            logger.info('Trying to PUT observation data for id: {0}'.format(observation_id))
            file_path = os.path.join(*[settings.OUTPUT_PATH, f])
            observation = {'payload': open(file_path, 'rb')}
            url = urljoin(base_url, observation_id)
            logger.debug('PUT file {0} to network API'.format(f))
            logger.debug('URL: {0}'.format(url))
            logger.debug('Headers: {0}'.format(headers))
            logger.debug('Observation file: {0}'.format(observation))
            response = requests.put(url, headers=headers,
                                    files=observation,
                                    verify=settings.VERIFY_SSL)
            if response.status_code == 200:
                logger.info('Success: status code 200')
                dst = os.path.join(settings.COMPLETE_OUTPUT_PATH, f)
            else:
                logger.error('Bad status code: {0}'.format(response.status_code))
                dst = os.path.join(settings.INCOMPLETE_OUTPUT_PATH, f)
            os.rename(f, dst)


def get_jobs():
    """Query SatNOGS Network API to GET jobs."""
    url = urljoin(settings.NETWORK_API_URL, 'jobs/')
    params = {'ground_station': settings.GROUND_STATION_ID}
    headers = {'Authorization': 'Token {0}'.format(settings.API_TOKEN)}
    logger.debug('URL: {0}'.format(url))
    logger.debug('Params: {0}'.format(params))
    logger.debug('Headers: {0}'.format(headers))
    logger.info('Trying to GET observation jobs from the network')
    response = requests.get(url, params=params, headers=headers, verify=settings.VERIFY_SSL)

    if not response.status_code == 200:
        raise Exception('Status code: {0} on request: {1}'.format(response.status_code, url))

    for job in scheduler.get_jobs():
        if job.name in [spawn_observer.__name__, spawn_receiver.__name__]:
            job.remove()

    for obj in response.json():
        start = parser.parse(obj['start'])
        job_id = str(obj['id'])
        kwargs = {'obj': obj}
        receiver_start = start - timedelta(seconds=settings.DEMODULATOR_INIT_TIME)
        logger.info('Adding new job: {0}'.format(job_id))
        logger.debug('Observation obj: {0}'.format(obj))
        scheduler.add_job(spawn_observer,
                          'date',
                          run_date=start,
                          id='observer_{0}'.format(job_id),
                          kwargs=kwargs)
        scheduler.add_job(spawn_receiver,
                          'date',
                          run_date=receiver_start,
                          id='receiver_{0}'.format(job_id),
                          kwargs=kwargs)

@@ -3044,17 +3044,53 @@
 .rename(
-f
+os.path.join(settings.OUTPUT_PATH, f)
 , dst)%0A%0A

Fix filepath when moving files to complete/incomplete dir.