#!/usr/bin/env python3
# -*- coding: utf-8 -*-

'''REST API for Telescope related operations'''

# System modules
from flask_restx import Namespace, Resource, fields

# Custom modules
import devices

api = Namespace('telescope', description='Telescope related operations')


@api.route("/lamp")
class Lamp(Resource):
    '''Manage the flat field lamp.'''

    @api.response(200, 'Success', fields.Boolean())
    def get(self):
        '''Check if the flat field lamp is on or off.'''
        res = {
            "response": devices.lamp.state,
            "error": devices.lamp.error,
        }
        return res

    @api.response(200, 'Success', fields.Boolean())
    # @api.expect(model)
    def put(self):
        '''Switch on or off the flat field lamp.'''
        state = api.payload
        devices.lamp.state = state
        res = {
            "response": devices.lamp.state,
            "error": devices.lamp.error,
        }
        return res


@api.route("/focuser")
class Focuser(Resource):
    '''Secondary mirror position.'''

    @api.response(200, 'Success', fields.Float())
    def get(self):
        '''Retrieve the secondary mirror position.'''
        res = {
            "response": devices.foc.position,
            "error": devices.foc.error,
        }
        return res


@api.route("/focuser/movement")
class FocuserMovement(Resource):
    '''Manage the secondary mirror position.'''

    @api.response(200, 'Success', fields.Boolean())
    def get(self):
        '''Check if the secondary mirror is moving.'''
        res = {
            "response": devices.foc.is_moving,
            "error": devices.foc.error,
        }
        return res

    @api.response(200, 'Success', fields.Float())
    def put(self):
        '''Update the secondary mirror position.'''
        target = api.payload
        devices.foc.position = target
        res = {
            "response": devices.foc.position,
            "error": devices.foc.error,
        }
        return res

    # def delete(self):
    #     '''Stop the movement.'''
    #     return


@api.route("/rotator")
class Rotator(Resource):
    '''Field derotator position.'''

    @api.response(200, 'Success', fields.Float())
    def get(self):
        '''Retrieve the field derotator position.'''
        res = {
            "response": devices.rot.position,
            "error": devices.rot.error,
        }
        return res


@api.route("/rotator/movement")
class RotatorMovement(Resource):
    '''Manage the field derotator position.'''

    @api.response(200, 'Success', fields.Boolean())
    def get(self):
        '''Check if the field derotator is moving.'''
        res = {
            "response": devices.rot.is_moving,
            "error": devices.rot.error,
        }
        return res

    @api.response(200, 'Success', fields.Float())
    def post(self):
        '''Set the field derotator to a new position.'''
        target = api.payload
        devices.rot.position = target
        res = {
            "response": devices.rot.position,
            "error": devices.rot.error,
        }
        return res


@api.route("/cover")
class Cover(Resource):
    '''Petals covering the primary mirror.'''

    @api.response(200, 'Success', fields.Float())
    def get(self):
        '''Retrieve the petals position.'''
        res = {
            "response": devices.tel.cover,
            "error": devices.tel.error,
        }
        return res


@api.route("/cover/movement")
class CoverMovement(Resource):
    '''Manage the primary mirror cover petals.'''

    # def get(self):
    #     '''Check if petals are moving.'''
    #     return

    @api.response(200, 'Success', fields.Boolean())
    def post(self):
        '''Set a new position for cover petals
        (open or closed).'''
        target = api.payload
        devices.tel.open = target
        res = {
            "response": devices.tel.open,
            "error": devices.tel.error,
        }
        return res

    # def delete(self):
    #     '''Stop the movement.'''
    #     return


@api.route("/error")
class Error(Resource):
    '''Manage the cabinet errors.'''

    @api.response(200, 'Success', fields.String())
    def get(self):
        '''Check if there are errors.'''
        res = {
            "response": devices.tel.status,
            "error": devices.tel.error,
        }
        return res

    @api.response(200, 'Success', fields.Integer())
    def delete(self):
        '''Try to clean the errors.'''
        error_number = api.payload
        res = {
            "response": devices.tel.clear(error_number),
            "error": devices.tel.error,
        }
        return res


@api.route("/clock")
class Clock(Resource):
    '''Telescope time from GPS.'''

    def get(self):
        '''Get the telescope time from GPS.'''
        res = {
            "response": devices.tel.clock,
            "error": devices.tel.error,
        }
        return res


@api.route("/coordinates")
class Coordinates(Resource):
    '''Telescope coordinates.'''

    def get(self):
        '''Get the telescope coordinates.'''
        res = {
            "response": devices.ast.coordinates,
            "error": devices.ast.error,
        }
        return res


@api.route("/coordinates/movement")
class CoordinatesMovement(Resource):
    '''Manage the pointing of the telescope.'''

    def get(self):
        '''Check the status of the telescope movement.'''
        res = {
            "response": devices.tel.is_moving,
            "error": devices.tel.error,
        }
        return res

    def delete(self):
        '''Stop the telescope movement.'''
        return devices.tel.abort()


@api.route("/coordinates/movement/radec")
class CoordinatesMovementRadec(Resource):
    '''Point the telescope in Ra, Dec.'''

    def post(self):
        '''Set new Ra and Dec coordinates.'''
        target = api.payload
        devices.tel.radec = target
        res = {
            "response": devices.tel.radec,
            "error": devices.tel.error,
        }
        return res


@api.route("/coordinates/movement/altaz")
class CoordinatesMovementAltaz(Resource):
    '''Point the telescope in Alt, Az.'''

    def post(self):
        '''Set new Alt and Az coordinates.'''
        target = api.payload
        devices.tel.altaz = target
        res = {
            "response": devices.tel.altaz,
            "error": devices.tel.error
        }
        return res


@api.route("/coordinates/movement/park")
class CoordinatesMovementPark(Resource):
    '''Park the telescope.'''

    def post(self):
        '''Send the telescope to park position.'''
        devices.tel.park = True
        res = {
            "response": devices.tel.park,
            "error": devices.tel.error,
        }
        return res


@api.route("/coordinates/movement/unpark")
class CoordinatesMovementUnpark(Resource):
    '''Unpark the telescope.'''

    def post(self):
        '''Remove the telescope from park position.'''
        devices.tel.park = False
        res = {"response": devices.tel.park,
               "error": devices.tel.error,
               }
        return res


@api.route("/coordinates/offset")
class CoordinatesOffset(Resource):
    '''Manage the coordinates offset.'''

    def get(self):
        '''Retrieve the telescope offset in Zdist, Az.'''
        res = {
            "response": devices.tel.offset,
            "error": devices.tel.error,
        }
        return res

    def put(self):
        '''Apply to the telescope new offsets in degrees.'''
        offset = api.payload
        devices.tel.offset = offset
        res = {
            "response": devices.tel.offset,
            "error": devices.tel.error,
        }
        return res


@api.route("/coordinates/tracking")
class CoordinatesTracking(Resource):
    '''Enable or disable the telescope tracking.'''

    def get(self):
        '''Check if the telescope is tracking or not.'''
        res = {
            "response": devices.tel.tracking,
            "error": devices.tel.error,
        }
        return res

    @api.response(200, 'Success', fields.Boolean())
    def put(self):
        '''Set the telescope in tracking mode or not'''
        tracking = api.payload
        devices.tel.tracking = tracking
        res = {
            "response": devices.tel.tracking,
            "error": devices.tel.error,
        }
        return res


@api.route("/power")
class Power(Resource):
    '''Manage the cabinet power.'''

    def get(self):
        '''Check if the telescope cabinet is on or off.'''
        res = {
            "response": devices.cab.state,
            "error": devices.cab.error,
        }
        return res

    @api.response(200, 'Success', fields.Boolean())
    def put(self):
        '''Switch on or off the telescope cabinet.'''
        power = api.payload
        devices.cab.state = power
        res = {
            "response": devices.cab.state,
            "error": devices.cab.error,
        }
        return res


# @api.route("/power/cycle")
# class PowerCycle(Resource):
#     '''Manage the telescope cabinet reboot.'''

#     def post(self):
#         '''Reboot the cabinet.'''
#         pass
