# Copyright (c) 2015 The New Mexico Consortium
# 
# {{{NMC-LICENSE
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
# }}}

class DiskEnclosure:
    def __init__(self, attrs):
        for k,v in attrs.iteritems():
            setattr(self, k, v)

    def __repr__(self):
        return '%s' % vars(self)

    def add_disk(self, disk):
        self.disks[int(disk.bay)] = disk

    @property
    def disks(self):
        '''Map of bay number to Disk objects'''
        if getattr(self, '_disks', None) is None:
            self._disks = {}
        return self._disks;

    @property
    def empty_bays(self):
        '''An array of bay numbers that are empty'''
        if getattr(self, '_empty_bays', None) is None:
            self._empty_bays = self.list_empty_bays()
        return self._empty_bays

    def list_empty_bays(self):
        empty_bays = []
        bays = sorted(self.disks.keys())
        expected = 0
        idx = 0

        while idx < len(bays):
            if bays[idx] != expected:
                empty_bays.append(expected)
            else:
                idx = idx + 1
            expected = expected + 1

        return empty_bays

    def locate_bay(self, bay, state = 'on'):
        self.controller.locate_bay(self.index, bay, state)

    def clear_locate(self):
        '''Clears the locate LED for all bays'''
        for bay in range(0, int(self.num_bays)):
            self.locate_bay(bay, 'off')
        
    def locate_empty_bays(self, state = 'on'):
        '''Locate empty bays in the enclosure'''
        for bay in self.empty_bays:
            self.locate_bay(bay, state)
