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

# 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."""
        return devices.lamp.state

    @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
        return devices.lamp.state

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

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

    
@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."""
        return devices.foc.is_moving

    @api.response(200, 'Success', fields.Float())
    def post(self):
        """Set the secondary mirror to a new position."""
        target = api.payload
        devices.foc.position = target
        return devices.foc.position

    # 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."""
        return devices.rot.position

    
@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."""
        return devices.rot.is_moving

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

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

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

@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
        return devices.tel.open

    # 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."""
        return devices.tel.status

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

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

    #@api.response(200, 'Success', fields.Float())
    def get(self):
        """Get the telescope time from GPS."""
        res = devices.tel.clock
        err = devices.tel.error
        return res if not err else {"Error": str(err)}
        return devices.tel.clock

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

    def get(self):
        """Get the telescope coordinates."""        
        return devices.ast.coordinates


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

    def get(self):
        """Check the status of the telescope movement."""
        return devices.tel.is_moving

    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
        return devices.tel.radec


@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
        return devices.tel.altaz


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

    def post(self):
        """Send the telescope to park position."""
        devices.tel.park = True
        return devices.tel.park

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

    def post(self):
        """Remove the telescope from park position."""
        devices.tel.park = False
        return devices.tel.park


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

    def get(self):
        """Retrieve the telescope offset in Zdist, Az."""
        return devices.tel.offset

    def put(self):
        """Apply to the telescope new offsets in degrees."""
        offset = api.payload
        devices.tel.offset = offset
        return devices.tel.offset

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

    def get(self):
        """Check if the telescope is tracking or not."""
        return devices.tel.tracking

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


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

    def get(self):
        """Check if the telescope cabinet is on or off."""
        pass

    def put(self):
        """Switch on or off the telescope cabinet."""
        pass

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

    def post(self):
        """Reboot the cabinet."""
        pass
