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

'''REST API for Dome related operations'''

# System modules
from flask_restx import Namespace, Resource, fields

# Custom modules
import devices

api = Namespace('dome', description='Dome related operations')

model_generic = api.model('Generic', {
    'error': fields.List(fields.String),
})

model_bool = api.clone('Boolean', model_generic, {
    'response': fields.Boolean,
})

model_int = api.clone('Integer', model_generic, {
    'response': fields.Integer,
})

model_float = api.clone('Float', model_generic, {
    'response': fields.Float,
})

sub_model_position = api.model('SubPosition', {
        "azimuth": fields.Float,
        "parked": fields.Boolean,
})

model_position = api.clone('Position', model_generic, {
    'response': fields.Nested(sub_model_position),
})


@api.route("/light")
class Light(Resource):
    '''Manage the dome illumination.'''

    @api.marshal_with(model_bool, 200)
    def get(self, **kwargs):
        '''Check if the dome illumination is on or off.'''
        res = {
            "response": devices.light.state,
            "error": devices.light.error,
        }
        return res

    @api.marshal_with(model_bool, 200)
    def put(self):
        '''Switch on or off the dome illumination.'''
        state = api.payload
        devices.light.state = state
        res = {
            "response": devices.light.state,
            "error": devices.light.error,
        }
        return res


@api.route("/position")
class Positiont(Resource):
    '''Get the position of the dome.'''

    @api.marshal_with(model_position, 200)
    def get(self):
        '''Check the azimuth of the dome, and if
        this corresponds to the parking position.'''
        res = {
            "response": {
                "azimuth": devices.dom.azimuth,
                "parked": devices.dom.is_parked,
            },
            "error": devices.dom.error,
        }
        return res


@api.route("/shutter")
class Shutter(Resource):
    '''Dome Shutter'''

    @api.marshal_with(model_int, 200)
    def get(self):
        '''Check the state of the dome shutter.'''
        res = {
            "response": devices.dom.shutter,
            "error": devices.dom.shutter,
        }
        return res


@api.route("/shutter/movement")
class ShutterMovement(Resource):
    '''Manage the movement of the dome shutter.'''

    def post(self):
        '''Move the shutter to a new position
        (open or closed).'''
        target = api.payload
        devices.dom.open = target
        res = {
            "response": devices.dom.open,
            "error": devices.dom.error,
        }
        return res

    def delete(self):
        '''Stop the movement of the shutter'''



@api.route("/position/slaved")
class PositionSlaved(Resource):
    '''Manage the minioning of the shutter
    to the telescope.'''

    @api.marshal_with(model_bool, 200)
    def get(self):
        '''Check if the dome is slaved
        to the telescope or not.'''
        res = {
            "response": devices.dom.slave,
            "error": devices.dom.error,
        }
        return res

    @api.marshal_with(model_bool, 200)
    def put(self):
        '''Make the dome slaved to the telescope
        or release it.'''
        slaved = api.payload
        devices.dom.slave = slaved
        res = {
            "response": devices.dom.slave,
            "error": devices.dom.error,
        }
        return res


@api.route("/position/sync")
class PositionSync(Resource):
    '''Manage the reference azimuth of the dome'''

    def put(self):
        '''Tell the dome that its current position
        corresponds to a given azimuth.'''
        new_azimuth = api.payload
        res = {
            "response": devices.dom.sync(new_azimuth),
            "error": devices.dom.error,
        }
        return res


@api.route("/position/movement")
class PositionMovement(Resource):
    '''Manage the movement of the dome.'''

    @api.marshal_with(model_bool, 200)
    def get(self):
        '''Return if the dome is moving or not.'''
        res = {
            "response": devices.dom.is_moving,
            "error": devices.dom.error,
        }
        return res

    def delete(self):
        '''Stop the movement of the dome.'''
        res = {
            "response": devices.dom.abort(),
            "error": devices.dom.error,
        }
        return res


@api.route("/position/movement/park")
class PositionMovementPark(Resource):
    '''Manage the dome parking.'''

    def post(self):
        '''Park the dome.'''
        res = {
            "response": devices.dom.park(),
            "error": devices.dom.error,
        }
        return res


@api.route("/position/movement/azimuth")
class PositionMovementAzimuth(Resource):
    '''Manage the position of the dome.'''

    @api.marshal_with(model_float, 200)
    def post(self):
        '''Set a new dome azimuth.'''
        azimuth = api.payload
        devices.dom.azimuth = azimuth
        res = {
            "response": devices.dom.azimuth,
            "error": devices.dom.error,
        }
        return res
