#/usr/bin/env python3.4
#
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Test script to test PBAP contact download between two devices which can run SL4A.
"""

import os
import time

from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
from acts.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test
from acts.base_test import BaseTestClass
from acts.test_utils.bt import bt_contacts_utils
from acts.test_utils.bt import bt_test_utils
from acts.test_utils.car import car_bt_utils
from acts.utils import exe_cmd
import acts.test_utils.bt.BtEnum as BtEnum

# Offset call logs by 1 minute
CALL_LOG_TIME_OFFSET_IN_MSEC = 60000
PSE_CONTACTS_FILE = "psecontacts.vcf"
PCE_CONTACTS_FILE = "pcecontacts.vcf"
MERGED_CONTACTS_FILE = "psecombined.vcf"
STANDART_CONTACT_COUNT = 100


class BtCarPbapTest(BluetoothBaseTest):
    contacts_destination_path = ""

    def __init__(self, controllers):
        BaseTestClass.__init__(self, controllers)
        self.pce = self.android_devices[0]
        self.pse = self.android_devices[1]
        self.pse2 = self.android_devices[2]
        self.contacts_destination_path = self.log_path + "/"

    def setup_class(self):
        if not super(BtCarPbapTest, self).setup_class():
            return False
        permissions_list = [
            "android.permission.READ_CONTACTS",
            "android.permission.WRITE_CONTACTS",
            "android.permission.READ_EXTERNAL_STORAGE"
        ]
        for permission in permissions_list:
            self.pse.adb.shell(
                "pm grant com.google.android.contacts {}".format(permission))
        for permission in permissions_list:
            self.pce.adb.shell("pm grant com.android.contacts {}".format(
                permission))

        # Pair the devices.
        # This call may block until some specified timeout in bt_test_utils.py.
        # Grace time inbetween stack state changes

        setup_multiple_devices_for_bt_test(self.android_devices)
        if not bt_test_utils.pair_pri_to_sec(self.pce, self.pse):
            self.log.error("Failed to pair.")
            return False
        time.sleep(3)
        if not bt_test_utils.pair_pri_to_sec(self.pce, self.pse2):
            self.log.error("Failed to pair.")
            return False

        # Disable the HFP and A2DP profiles. This will ensure only PBAP
        # gets connected. Also, this will eliminate the auto-connect loop.
        car_bt_utils.set_car_profile_priorities_off(self.pce, self.pse)
        car_bt_utils.set_car_profile_priorities_off(self.pce, self.pse2)

        # Enable PBAP on PSE & PCE.

        self.pse.droid.bluetoothChangeProfileAccessPermission(
            self.pce.droid.bluetoothGetLocalAddress(),
            BtEnum.BluetoothProfile.PBAP_SERVER.value,
            BtEnum.BluetoothAccessLevel.ACCESS_ALLOWED.value)

        self.pse2.droid.bluetoothChangeProfileAccessPermission(
            self.pce.droid.bluetoothGetLocalAddress(),
            BtEnum.BluetoothProfile.PBAP_SERVER.value,
            BtEnum.BluetoothAccessLevel.ACCESS_ALLOWED.value)

        bt_test_utils.set_profile_priority(
            self.pce, self.pse, [BtEnum.BluetoothProfile.PBAP_CLIENT],
            BtEnum.BluetoothPriorityLevel.PRIORITY_ON)
        bt_test_utils.set_profile_priority(
            self.pce, self.pse2, [BtEnum.BluetoothProfile.PBAP_CLIENT],
            BtEnum.BluetoothPriorityLevel.PRIORITY_ON)

        return True

    def setup_test(self):
        if not super(BtCarPbapTest, self).setup_test():
            return False
        self.pse.droid.callLogsEraseAll()
        if not (bt_contacts_utils.erase_contacts(self.pse) and
                bt_contacts_utils.erase_contacts(self.pce)):
            return False
        # Allow all content providers to synchronize.
        time.sleep(1)
        return True

    def teardown_test(self):
        if not super(BtCarPbapTest, self).teardown_test():
            return False
        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse.droid.bluetoothGetLocalAddress())
        bt_contacts_utils.erase_contacts(self.pse)
        return True

    def verify_contacts_match(self):
        bt_contacts_utils.export_device_contacts_to_vcf(
            self.pce, self.contacts_destination_path, PCE_CONTACTS_FILE)
        return bt_contacts_utils.count_contacts_with_differences(
            self.contacts_destination_path, PCE_CONTACTS_FILE,
            PSE_CONTACTS_FILE) == 0

    def connect_and_verify(self, count):
        bt_test_utils.connect_pri_to_sec(
            self.pce, self.pse,
            set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
        bt_contacts_utils.wait_for_phone_number_update_complete(self.pce,
                                                                count)
        contacts_added = self.verify_contacts_match()
        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse.droid.bluetoothGetLocalAddress())
        contacts_removed = bt_contacts_utils.wait_for_phone_number_update_complete(
            self.pce, 0)
        return contacts_added and contacts_removed

    #@BluetoothTest(UUID=7dcdecfc-42d1-4f41-b66e-823c8f161356)
    @BluetoothBaseTest.bt_test_wrap
    def test_pbap_connect_and_disconnect(self):
        """Test Connectivity

        Test connecting with the server enabled and disabled

        Precondition:
        1. Devices are paired.

        Steps:
        1. Disable permission on PSE to prevent PCE from connecting
        2. Attempt to connect PCE to PSE
        3. Verify connection failed
        4. Enable permission on PSE to allow PCE to connect
        5. Attempt to connect PCE to PSE
        6. Verify connection succeeded

        Returns:
            Pass if True
            Fail if False
        """
        self.pse.droid.bluetoothChangeProfileAccessPermission(
            self.pce.droid.bluetoothGetLocalAddress(),
            BtEnum.BluetoothProfile.PBAP_SERVER.value,
            BtEnum.BluetoothAccessLevel.ACCESS_DENIED.value)
        if bt_test_utils.connect_pri_to_sec(
                self.pce, self.pse,
                set([BtEnum.BluetoothProfile.PBAP_CLIENT.value])):
            self.log.error("Client connected and shouldn't be.")
            return False

        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse.droid.bluetoothGetLocalAddress())

        self.pse.droid.bluetoothChangeProfileAccessPermission(
            self.pce.droid.bluetoothGetLocalAddress(),
            BtEnum.BluetoothProfile.PBAP_SERVER.value,
            BtEnum.BluetoothAccessLevel.ACCESS_ALLOWED.value)

        if not bt_test_utils.connect_pri_to_sec(
                self.pce, self.pse,
                set([BtEnum.BluetoothProfile.PBAP_CLIENT.value])):
            self.log.error("No client connected and should be.")
            return False

        return True

    #@BluetoothTest(UUID=1733efb9-71af-4956-bd3a-0d3167d94d0c)
    @BluetoothBaseTest.bt_test_wrap
    def test_contact_download(self):
        """Test Contact Download

        Test download of contacts from a clean state.

        Precondition:
        1. Devices are paired.

        Steps:
        1. Erase contacts from PSE and PCE.
        2. Add a predefined list of contacts to PSE.
        3. Connect PCE to PSE to perform transfer.
        4. Compare transfered contacts.
        5. Disconnect.
        6. Verify PCE cleaned up contact list.

        Returns:
            Pass if True
            Fail if False
        """
        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE_CONTACTS_FILE, 100)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE_CONTACTS_FILE)
        bt_test_utils.connect_pri_to_sec(
            self.pce, self.pse,
            set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
        bt_contacts_utils.wait_for_phone_number_update_complete(
            self.pce, phone_numbers_added)
        if not self.verify_contacts_match():
            return False
        return bt_contacts_utils.erase_contacts(self.pce)

    #@BluetoothTest(UUID=99dc6ac6-b7cf-45ce-927b-8c4ebf8ab664)
    @BluetoothBaseTest.bt_test_wrap
    def test_modify_phonebook(self):
        """Test Modify Phonebook

        Test changing contacts and reconnecting PBAP.

        Precondition:
        1. Devices are paired.

        Steps:
        1. Add a predefined list of contacts to PSE.
        2. Connect PCE to PSE to perform transfer.
        3. Verify that contacts match.
        4. Change some contacts on the PSE.
        5. Reconnect PCE to PSE to perform transfer.
        6. Verify that new contacts match.

        Returns:
            Pass if True
            Fail if False
        """
        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE_CONTACTS_FILE, 100)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE_CONTACTS_FILE)
        if not self.connect_and_verify(phone_numbers_added):
            return False

        bt_contacts_utils.erase_contacts(self.pse)
        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE_CONTACTS_FILE, 110, 2)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE_CONTACTS_FILE)
        return self.connect_and_verify(phone_numbers_added)

    #@BluetoothTest(UUID=bbe31bf5-51e8-4175-b266-1c7750e44f5b)
    @BluetoothBaseTest.bt_test_wrap
    def test_special_contacts(self):
        """Test Special Contacts

        Test numerous special cases of contacts that could cause errors.

        Precondition:
        1. Devices are paired.

        Steps:
        1. Add a predefined list of contacts to PSE that includes special cases:
        2. Connect PCE to PSE to perform transfer.
        3. Verify that contacts match.

        Returns:
            Pass if True
            Fail if False
        """

        vcards = []

        # Generate a contact with no email address
        current_contact = bt_contacts_utils.VCard()
        current_contact.first_name = "Mr."
        current_contact.last_name = "Smiley"
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a 2nd contact with the same name but different phone number
        current_contact = bt_contacts_utils.VCard()
        current_contact.first_name = "Mr."
        current_contact.last_name = "Smiley"
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a contact with no name
        current_contact = bt_contacts_utils.VCard()
        current_contact.email = "{}@gmail.com".format(
            bt_contacts_utils.generate_random_string())
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a contact with random characters in its name
        current_contact = bt_contacts_utils.VCard()
        current_contact.first_name = bt_contacts_utils.generate_random_string()
        current_contact.last_name = bt_contacts_utils.generate_random_string()
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a contact with only a phone number
        current_contact = bt_contacts_utils.VCard()
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a 2nd contact with only a phone number
        current_contact = bt_contacts_utils.VCard()
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        bt_contacts_utils.create_new_contacts_vcf_from_vcards(
            self.contacts_destination_path, PSE_CONTACTS_FILE, vcards)

        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE_CONTACTS_FILE)

        return self.connect_and_verify(phone_numbers_added)

    #@BluetoothTest(UUID=2aa2bd00-86cc-4f39-a06a-90b17ea5b320)
    @BluetoothBaseTest.bt_test_wrap
    def test_call_log(self):
        """Test Call Log

        Test that Call Logs are transfered

        Precondition:
        1. Devices are paired.

        Steps:
        1. Add a predefined list of calls to the PSE call log.
        2. Connect PCE to PSE to allow call log transfer
        3. Verify the Missed, Incoming, and Outgoing Call History

        Returns:
            Pass if True
            Fail if False
        """

        bt_contacts_utils.add_call_log(
            self.pse, bt_contacts_utils.INCOMMING_CALL_TYPE,
            bt_contacts_utils.generate_random_phone_number().phone_number,
            int(time.time() * 1000))
        bt_contacts_utils.add_call_log(
            self.pse, bt_contacts_utils.INCOMMING_CALL_TYPE,
            bt_contacts_utils.generate_random_phone_number().phone_number,
            int(time.time()) * 1000 - 4 * CALL_LOG_TIME_OFFSET_IN_MSEC)
        bt_contacts_utils.add_call_log(
            self.pse, bt_contacts_utils.OUTGOING_CALL_TYPE,
            bt_contacts_utils.generate_random_phone_number().phone_number,
            int(time.time()) * 1000 - CALL_LOG_TIME_OFFSET_IN_MSEC)
        bt_contacts_utils.add_call_log(
            self.pse, bt_contacts_utils.MISSED_CALL_TYPE,
            bt_contacts_utils.generate_random_phone_number().phone_number,
            int(time.time()) * 1000 - 2 * CALL_LOG_TIME_OFFSET_IN_MSEC)
        bt_contacts_utils.add_call_log(
            self.pse, bt_contacts_utils.MISSED_CALL_TYPE,
            bt_contacts_utils.generate_random_phone_number().phone_number,
            int(time.time()) * 1000 - 2 * CALL_LOG_TIME_OFFSET_IN_MSEC)

        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse.droid.bluetoothGetLocalAddress())
        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse2.droid.bluetoothGetLocalAddress())

        bt_test_utils.connect_pri_to_sec(
            self.pce, self.pse,
            set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
        pse_call_log_count = self.pse.droid.callLogGetCount()
        self.log.info("Waiting for {} call logs to be transfered".format(
            pse_call_log_count))
        bt_contacts_utils.wait_for_call_log_update_complete(self.pce,
                                                            pse_call_log_count)

        if not bt_contacts_utils.get_and_compare_call_logs(
                self.pse, self.pce, bt_contacts_utils.INCOMMING_CALL_TYPE):
            return False
        if not bt_contacts_utils.get_and_compare_call_logs(
                self.pse, self.pce, bt_contacts_utils.OUTGOING_CALL_TYPE):
            return False
        if not bt_contacts_utils.get_and_compare_call_logs(
                self.pse, self.pce, bt_contacts_utils.MISSED_CALL_TYPE):
            return False

        return True

    def test_multiple_phones(self):
        """Test Multiple Phones

        Test that connects two phones and confirms contacts are transfered
        and merged while still being associated with their original phone.

        Precondition:
        1. Devices are paired.

        Steps:
        1. Add a unique list of contacts to PSE on each phone.
        2. Connect PCE to PSE 1 to perform transfer.
        3. Verify contacts match.
        4. Connect PCE to PSE 2 to perform transfer.
        5. Verify that the PCE has a union set of contacts from
           PSE 1 and PSE 2.
        6. Disconnect PCE from PSE 1 to clean up contacts.
        7. Verify that only PSE 2 contacts remain on PCE and they match.
        8. Disconnect PCE from PSE 2 to clean up contacts.

        Returns:
           Pass if True
           Fail if False
        """

        PSE1_CONTACTS_FILE = "{}{}".format(PSE_CONTACTS_FILE, "1")
        PSE2_CONTACTS_FILE = "{}{}".format(PSE_CONTACTS_FILE, "2")

        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE1_CONTACTS_FILE, 100)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE1_CONTACTS_FILE)
        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE2_CONTACTS_FILE, 100)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse2, self.contacts_destination_path, PSE2_CONTACTS_FILE)

        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse.droid.bluetoothGetLocalAddress())
        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse2.droid.bluetoothGetLocalAddress())

        bt_test_utils.connect_pri_to_sec(
            self.pce, self.pse,
            set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
        bt_contacts_utils.wait_for_phone_number_update_complete(self.pce, 100)
        bt_contacts_utils.export_device_contacts_to_vcf(
            self.pce, self.contacts_destination_path, PCE_CONTACTS_FILE)
        pse1_matches = bt_contacts_utils.count_contacts_with_differences(
            self.contacts_destination_path, PCE_CONTACTS_FILE,
            PSE1_CONTACTS_FILE) == 0

        bt_test_utils.connect_pri_to_sec(
            self.pce, self.pse2,
            set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))

        bt_contacts_utils.wait_for_phone_number_update_complete(self.pce, 200)

        bt_contacts_utils.export_device_contacts_to_vcf(
            self.pce, self.contacts_destination_path, PCE_CONTACTS_FILE)

        merged_file = open('{}{}'.format(self.contacts_destination_path,
                                         MERGED_CONTACTS_FILE), 'w')
        for contacts_file in [PSE1_CONTACTS_FILE, PSE2_CONTACTS_FILE]:
            infile = open(self.contacts_destination_path + contacts_file)
            merged_file.write(infile.read())

        self.log.info("Checking combined phonebook.")
        pse1andpse2_matches = bt_contacts_utils.count_contacts_with_differences(
            self.contacts_destination_path, PCE_CONTACTS_FILE,
            MERGED_CONTACTS_FILE) == 0

        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse.droid.bluetoothGetLocalAddress())
        bt_contacts_utils.wait_for_phone_number_update_complete(self.pce, 100)

        self.log.info("Checking phonebook after disconnecting first device.")
        bt_contacts_utils.export_device_contacts_to_vcf(
            self.pce, self.contacts_destination_path, PCE_CONTACTS_FILE)
        pse2_matches = bt_contacts_utils.count_contacts_with_differences(
            self.contacts_destination_path, PCE_CONTACTS_FILE,
            PSE2_CONTACTS_FILE) == 0

        bt_contacts_utils.erase_contacts(self.pse)
        bt_contacts_utils.erase_contacts(self.pse2)
        return pse1_matches and pse2_matches and pse1andpse2_matches
