#!/usr/bin/env python
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import dbus
import dbus.service

from swindle import entity

class Manager(entity.Entity):
  _I_MANAGER = 'org.chromium.flimflam.Manager'

  def __init__(self, bus):
    entity.Entity.__init__(self, bus, '/')
    self.active_profile = None
    self.profiles = []
    self.devices = []
    self._services = []
    self.bus = bus
    self.state = 'online'
    self.offline_mode = False
    self.techs = []
    self.agents = []
    self.default_tech = None
    self.service_order = 'ethernet,bluetooth,wifi,wimax,cellular'
    self.debugtags = []

  def profile(self):
    return self.active_profile

  def add_profile(self, obj):
    self.profiles.append(obj)
    if not self.active_profile:
      self.active_profile = self.profiles[0]

  def add_device(self, obj):
    self.devices.append(obj)
    if obj.technology() not in self.techs:
      self.techs.append(obj.technology())
    if not self.default_tech:
      self.default_tech = self.techs[0]

  def add_service(self, obj):
    self._services.append(obj)
    self.PropertyChanged('Services', self.services())

  def del_service(self, obj):
    self._services.remove(obj)
    self.PropertyChanged('Services', self.services())

  def services(self):
    return dbus.Array([x.path() for x in self._services], variant_level=1)

  def enabled_techs(self):
    ts = [x.technology() for x in self.devices if x.enabled()]
    if not ts:
      return None
    return dbus.Array(set(ts), variant_level=1)

  @dbus.service.signal(_I_MANAGER, signature='sv')
  def PropertyChanged(self, key, val):
    self.log('PropertyChanged %s %s', key, val)

  @dbus.service.method(_I_MANAGER, in_signature='', out_signature='a{sv}')
  def GetProperties(self):
    self.log('GetProperties')
    r = {'ActiveProfile': self.active_profile.path()}
    r['Profiles'] = dbus.Array([x.path() for x in self.profiles],
                               variant_level=1)
    if self._services:
      r['Services'] = self.services()
    if self.devices:
      r['Devices'] = dbus.Array([x.path() for x in self.devices],
                                variant_level=1)
    r['State'] = dbus.String(self.state, variant_level=1)
    r['OfflineMode'] = dbus.Boolean(self.offline_mode, variant_level=1)
    techs = set([x.technology() for x in self.devices])
    if techs:
      r['AvailableTechnologies'] = dbus.Array(techs, variant_level=1)
    ontechs = self.enabled_techs()
    if ontechs:
      r['EnabledTechnologies'] = ontechs
    conntechs = set([x.technology() for x in self.devices if x.connected()])
    if conntechs:
      r['ConnectedTechnologies'] = dbus.Array(conntechs, variant_level=1)
    return r

  @dbus.service.method(_I_MANAGER, in_signature='sv', out_signature='')
  def SetProperty(self, key, value):
    self.log('SetProperty %s %s', key, val)

  @dbus.service.method(_I_MANAGER, in_signature='', out_signature='s')
  def GetState(self):
    self.log('GetState')
    return self.state

  @dbus.service.method(_I_MANAGER, in_signature='s', out_signature='o')
  def CreateProfile(self, name):
    self.log('CreateProfile %s', name)
    p = Profile(self.bus, name)
    self.add_profile(p)
    return p.path()

  @dbus.service.method(_I_MANAGER, in_signature='o', out_signature='')
  def RemoveProfile(self, obj):
    self.log('RemoveProfile %s', name)
    self.profiles = [x for x in self.profiles if x.path() != obj]

  @dbus.service.method(_I_MANAGER, in_signature='s')
  def RequestScan(self, scantype):
    self.log('RequestScan %s', scantype)

  @dbus.service.method(_I_MANAGER,
                       in_signature='s',
                       out_signature='')
  def EnableTechnology(self, tech):
    self.log('EnableTechnology %s', tech)
    for d in self.devices:
      if d.technology() == tech:
        d.enable()
    self.PropertyChanged('EnabledTechnologies', self.enabled_techs())

  @dbus.service.method(_I_MANAGER,
                       in_signature='s',
                       out_signature='')
  def DisableTechnology(self, tech):
    self.log('DisableTechnology %s', tech)
    for d in self.devices:
      if d.technology() == tech:
        d.disable()
    self.PropertyChanged('EnabledTechnologies', self.enabled_techs())

  @dbus.service.method(_I_MANAGER,
                       in_signature='a{sv}',
                       out_signature='o')
  def GetService(self, service):
    self.log('GetService %s', service)

  @dbus.service.method(_I_MANAGER,
                       in_signature='a{sv}',
                       out_signature='o')
  def GetWifiService(self, service):
    self.log('GetWifiService %s', service)

  @dbus.service.method(_I_MANAGER,
                       in_signature='a{sv}',
                       out_signature='')
  def ConfigureWifiService(self, service):
    self.log('ConfigureWifiService %s', service)

  @dbus.service.method(_I_MANAGER, in_signature='o', out_signature='')
  def RegisterAgent(self, obj):
    self.log('RegisterAgent %s', obj)
    self.agents.append(obj)

  @dbus.service.method(_I_MANAGER, in_signature='o', out_signature='')
  def UnregisterAgent(self, obj):
    self.log('UnregisterAgent %s', obj)
    self.agents.remove(obj)

  @dbus.service.method(_I_MANAGER, in_signature='', out_signature='s')
  def GetDebugTags(self):
    self.log('GetDebugTags')
    return ','.join(self.debugtags)

  @dbus.service.method(_I_MANAGER, in_signature='s', out_signature='')
  def SetDebugTags(self, tags):
    self.log('SetDebugTags %s', tags)

  @dbus.service.method(_I_MANAGER, in_signature='', out_signature='s')
  def GetServiceOrder(self):
    self.log('GetServiceOrder')
    return self.service_order

  @dbus.service.method(_I_MANAGER, in_signature='s', out_signature='')
  def SetServiceOrder(self, order):
    self.log('SetServiceOrder %s', order)
    self.service_order = order
