from pacman.model.graphs.application.impl.application_vertex\
    import ApplicationVertex
from pacman.model.decorators.overrides import overrides
from pacman.model.resources.resource_container import ResourceContainer
from pacman.model.resources.dtcm_resource import DTCMResource
from pacman.model.resources.sdram_resource import SDRAMResource
from pacman.model.graphs.machine.impl.machine_spinnaker_link_vertex \
    import MachineSpiNNakerLinkVertex
from pacman.model.graphs.abstract_spinnaker_link_vertex \
    import AbstractSpiNNakerLinkVertex
from pacman.model.resources.cpu_cycles_per_tick_resource \
    import CPUCyclesPerTickResource

import sys


class ApplicationSpiNNakerLinkVertex(
        ApplicationVertex, AbstractSpiNNakerLinkVertex):
    """ A virtual vertex on a SpiNNaker Link
    """

    __slots__ = (
        "_n_atoms",
        "_spinnaker_link_id",
        "_board_address",
        "_virtual_chip_x",
        "_virtual_chip_y"
    )

    def __init__(
            self, n_atoms, spinnaker_link_id, board_address=None, label=None,
            constraints=None, max_atoms_per_core=sys.maxint):
        ApplicationVertex.__init__(
            self, label=label, constraints=constraints,
            max_atoms_per_core=max_atoms_per_core)
        self._n_atoms = n_atoms
        self._spinnaker_link_id = spinnaker_link_id
        self._board_address = board_address
        self._virtual_chip_x = None
        self._virtual_chip_y = None

    @property
    @overrides(AbstractSpiNNakerLinkVertex.spinnaker_link_id)
    def spinnaker_link_id(self):
        return self._spinnaker_link_id

    @property
    @overrides(AbstractSpiNNakerLinkVertex.board_address)
    def board_address(self):
        return self._board_address

    @property
    @overrides(AbstractSpiNNakerLinkVertex.virtual_chip_x)
    def virtual_chip_x(self):
        return self._virtual_chip_x

    @property
    @overrides(AbstractSpiNNakerLinkVertex.virtual_chip_y)
    def virtual_chip_y(self):
        return self._virtual_chip_y

    @overrides(AbstractSpiNNakerLinkVertex.set_virtual_chip_coordinates)
    def set_virtual_chip_coordinates(self, virtual_chip_x, virtual_chip_y):
        self._virtual_chip_x = virtual_chip_x
        self._virtual_chip_y = virtual_chip_y

    @property
    @overrides(ApplicationVertex.n_atoms)
    def n_atoms(self):
        return self._n_atoms

    @overrides(ApplicationVertex.get_resources_used_by_atoms)
    def get_resources_used_by_atoms(self, vertex_slice):
        return ResourceContainer(
            dtcm=DTCMResource(0), sdram=SDRAMResource(0),
            cpu_cycles=CPUCyclesPerTickResource(0)
        )

    @overrides(ApplicationVertex.create_machine_vertex)
    def create_machine_vertex(
            self, vertex_slice, resources_required, label=None,
            constraints=None):
        vertex = MachineSpiNNakerLinkVertex(
            self._spinnaker_link_id, self._board_address, label, constraints)
        vertex.set_virtual_chip_coordinates(
            self._virtual_chip_x, self._virtual_chip_y)
        return vertex
