# Lint as: python2, python3
# Copyright (c) 2011 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.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import dbus, logging

from six.moves import zip

from autotest_lib.client.common_lib import error

sample = {
    'pdu' :
      '07914140540510F0040B916171056429F500001190804181106904D4F29C0E',
    'parsed' :
      {'text' : 'Test',
       'number' : '+16175046925',
       'timestamp' : '110908141801-04',
       'smsc' : '+14044550010'
       }
    }

sample_multipart = {
    'pdu' :
      ['07912160130320F8440B916171056429F5000011909161037469A0050003920201A9'
       'E5391DF43683E6EF7619C47EBBCF207A194F0789EB74D03D4D47BFEB7450D89D0791'
       'D366737A5C67D3416374581E1ED3CBF23928ED1EB3EBE43219947683E8E832A85D9E'
       'CFC3E7B20B4445A7E72077B94C9E83E86F90B80C7ADBCB72101D5D06B1CBEE331D0D'
       'A2A3E5E539FACD2683CC6F39888E2E83D8EF71980D9ABFCDF47B585E06D1DF',
       '07912160130320F5440B916171056429F50000119091610384691505000392020241'
       'E437888E2E83E670769AEE02'],
    'parsed' :
      {'text' : 'Test of some long text but without any difficult characters'
       ' included in the message. This needs to be over the length threshold'
       ' for the local software to do the split.',
       'number' : '+16175046925',
       'timestamp' : '110919163047-04',
       'smsc' : '+12063130028'
       }
    }


class SmsStore(object):
    '''SMS content management - this maintains an internal model of the
    index->PDU mapping that the fakemodem program should be returning so
    that tests can add and remove individual PDUs and handles generating
    the correct set of responses, including the complete SMS list.
    '''

    def __init__(self, fakemodem):
        self.fakemodem = fakemodem
        self.smsdict = {}
        self.fakemodem.SetResponse('\+CMGR=', '', '+CMS ERROR: 321')
        self.fakemodem.SetResponse('\+CMGD=', '', '+CMS ERROR: 321')
        self._sms_regen_list()

    def sms_insert(self, index, pdu):
        '''Add a SMS to the fake modem's list.'''
        smsc_len = int(pdu[0:1], 16)
        mlen = len(pdu)/2 - smsc_len - 1

        self.fakemodem.RemoveResponse('\+CMGD=')
        self.fakemodem.RemoveResponse('\+CMGR=')
        self.fakemodem.SetResponse('\+CMGD=%d' % (index), '', '')
        self.fakemodem.SetResponse('\+CMGR=%d' % (index),
                                   '+CMGR: 1,,%d\r\n%s' % (mlen, pdu), '')
        self.fakemodem.SetResponse('\+CMGR=', '', '+CMS ERROR: 321')
        self.fakemodem.SetResponse('\+CMGD=', '', '+CMS ERROR: 321')

        self.smsdict[index] = pdu
        self._sms_regen_list()

    def sms_receive(self, index, pdu):
        '''Add a SMS to the fake modem's list, like sms_insert(), and generate
        an unsolicited new-sms message.'''
        self.sms_insert(index, pdu)
        self.fakemodem.SendUnsolicited('+CMTI: "ME",%d'%(index))

    def sms_remove(self, index):
        '''Remove a SMS from the fake modem's list'''
        self.fakemodem.RemoveResponse('\+CMGR=%d' % (index))
        self.fakemodem.RemoveResponse('\+CMGD=%d' % (index))
        del self.smsdict[index]
        self._sms_regen_list()

    def _sms_regen_list(self):
        response = ''
        keys = list(self.smsdict.keys())
        keys.sort()
        for i in keys:
            pdu = self.smsdict[i]
            smsc_len = int(pdu[0:1],16)
            mlen = len(pdu)/2 - smsc_len - 1
            response = response + '+CMGL: %d,1,,%d\r\n%s\r\n' % (i, mlen, pdu)
        self.fakemodem.SetResponse('\+CMGL=4', response, '')


class SmsTest(object):
    def __init__(self, gsmsms):
        self.gsmsms = gsmsms

    def compare(self, expected, got):
        '''Compare two SMS dictionaries, discounting the index number if
        not specified in the first.'''
        if expected == got:
            return True
        if 'index' in expected:
            return False
        if 'index' not in got:
            return False
        got = dict(got)
        del got['index']
        return expected == got

    def compare_list(self, expected_list, got_list):
        if len(expected_list) != len(got_list):
            return False
        # There must be a more Pythonic way to do this
        for (expected,got) in zip(expected_list, got_list):
            if self.compare(expected, got) == False:
                return False
        return True

    def test_get(self, index, expected):
        try:
            sms = self.gsmsms.Get(index)
        except dbus.DBusException as db:
            if expected is not None:
                raise
            return

        if expected is None:
            logging.info('Got %s' % sms)
            raise error.TestFail('SMS.Get(%d) succeeded unexpectedly' %
                                 index)
        if self.compare(expected, sms) == False:
            logging.info('Got %s, expected %s' % (sms, expected))
            raise error.TestFail('SMS.Get(%d) did not match expected values' %
                                 index)

    def test_delete(self, index, expected_success):
        try:
            self.gsmsms.Delete(index)
            if expected_success == False:
                raise error.TestFail('SMS.Delete(%d) succeeded unexpectedly' %
                                     index)
        except dbus.DBusException as db:
            if expected_success:
                raise

    def test_list(self, expected_list):
        sms_list = self.gsmsms.List()
        if self.compare_list(expected_list, sms_list) == False:
            logging.info('Got %s, expected %s' % (sms_list, expected_list))
            raise error.TestFail('SMS.List() did not match expected values')

    def test_has_none(self):
        '''Test that the SMS interface has no messages.'''
        self.test_list([])
        self.test_get(1, None)
        self.test_delete(1, False)
        self.test_delete(2, False)

    def test_has_one(self, parsed_sms):
        '''Test that the SMS interface has exactly one message at index 1
        As a side effect, deletes the message.'''
        self.test_list([parsed_sms])
        self.test_get(1, parsed_sms)
        self.test_get(2, None)
        self.test_delete(2, False)
        self.test_delete(1, True)
