/*
    Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
    и других спецификаций для функционирования компактных приложений на языке
    Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

    Copyright © 2016–2017, 2019–2022 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package javax.bluetooth;

public class DiscoveryAgent extends Object
{
    public static final int NOT_DISCOVERABLE = 0x000000;
    public static final int GIAC = 0x9e8b33;
    public static final int LIAC = 0x9e8b00;
    public static final int CACHED = 0;
    public static final int PREKNOWN = 1;

    private final RemoteDevice[] emptyRemoteDeviceList;
    Thread inquiryOperation;
    Thread searchOperation;
    private final Object monitor;

    DiscoveryAgent() {
        this.emptyRemoteDeviceList = new RemoteDevice[0];
        this.monitor = new Object();
    }

    public boolean cancelInquiry(DiscoveryListener listener) {
        if(listener == null)
        {
            throw new NullPointerException("DiscoveryAgent.cancelInquiry: аргумент listener равен нулевой ссылке.");
        }
        return false;
    }

    public boolean cancelServiceSearch(int transactionID) {
        return false;
    }

    public boolean startInquiry(int accessCode, final DiscoveryListener listener) throws BluetoothStateException {
        int error;
        Thread operation;
        if(accessCode < 0x9e8b00 || accessCode > 0x9e8b3f)
        {
            throw new IllegalArgumentException("DiscoveryAgent.startInquiry: аргумент accessCode выходит из диапазона.");
        }
        if(listener == null)
        {
            throw new NullPointerException("DiscoveryAgent.startInquiry: аргумент listener равен нулевой ссылке.");
        }
        error = 0;
        synchronized(monitor)
        {
            label0:
            {
                if(inquiryOperation != null)
                {
                    error = 1;
                    operation = null;
                    break label0;
                }
                inquiryOperation = operation = new Thread() {
                    public void run() {
                        try
                        {
                            listener.inquiryCompleted(DiscoveryListener.INQUIRY_COMPLETED);
                        }
                        finally
                        {
                            (DiscoveryAgent.this).inquiryOperation = null;
                        }
                    }
                };
            }
        }
        if(error == 1)
        {
            throw new BluetoothStateException("DiscoveryAgent.startInquiry: выполняется другая операция.");
        }
        operation.start();
        return true;
    }

    public int searchServices(int[] attrs, UUID[] uuids, RemoteDevice device, final DiscoveryListener listener) throws BluetoothStateException {
        int error;
        int attrsLen;
        int uuidsLen;
        int[] attrsCopy;
        UUID[] uuidsCopy;
        Thread operation;
        if(attrs == null)
        {
            attrsLen = 0;
            attrsCopy = null;
        } else
        {
            if((attrsLen = attrs.length) <= 0)
            {
                throw new IllegalArgumentException("DiscoveryAgent.searchServices: аргумент attrs имеет нулевую длину.");
            }
            Array.copy(attrs, 0, attrsCopy = new int[attrsLen], 0, attrsLen);
            for(int i = 0; i < attrsLen; i++)
            {
                int attr;
                if((attr = attrsCopy[i]) < 0 || attr > 0xffff)
                {
                    throw new IllegalArgumentException("DiscoveryAgent.searchServices: аргумент attrs содержит недопустимые элементы.");
                }
                if(Array.findf(attrsCopy, i + 1, attr) < attrsLen)
                {
                    throw new IllegalArgumentException("DiscoveryAgent.searchServices: аргумент attrs содержит одинаковые элементы.");
                }
            }
        }
        if(uuids == null)
        {
            throw new NullPointerException("DiscoveryAgent.searchServices: аргумент uuids равен нулевой ссылке.");
        }
        if((uuidsLen = uuids.length) <= 0)
        {
            throw new IllegalArgumentException("DiscoveryAgent.searchServices: аргумент uuids имеет нулевую длину.");
        }
        Array.copy(uuids, 0, uuidsCopy = new UUID[uuidsLen], 0, uuidsLen);
        for(int i = 0; i < uuidsLen; i++)
        {
            UUID uuid;
            if((uuid = uuidsCopy[i]) == null)
            {
                throw new NullPointerException("DiscoveryAgent.searchServices: аргумент uuids содержит нулевую ссылку.");
            }
            if(Array.findf(uuidsCopy, i + 1, uuid) < uuidsLen)
            {
                throw new IllegalArgumentException("DiscoveryAgent.searchServices: аргумент uuids содержит одинаковые элементы.");
            }
            for(int j = i + 1; j < uuidsLen; j++) if(uuid.realEquals(uuidsCopy[j]))
            {
                throw new IllegalArgumentException("DiscoveryAgent.searchServices: аргумент uuids содержит одинаковые элементы.");
            }
        }
        if(device == null)
        {
            throw new NullPointerException("DiscoveryAgent.searchServices: аргумент device равен нулевой ссылке.");
        }
        if(listener == null)
        {
            throw new NullPointerException("DiscoveryAgent.searchServices: аргумент listener равен нулевой ссылке.");
        }
        error = 0;
        synchronized(monitor)
        {
            label0:
            {
                if(searchOperation != null)
                {
                    error = 1;
                    operation = null;
                    break label0;
                }
                searchOperation = operation = new Thread() {
                    public void run() {
                        try
                        {
                            listener.serviceSearchCompleted(0x21cd, DiscoveryListener.SERVICE_SEARCH_COMPLETED);
                        }
                        finally
                        {
                            (DiscoveryAgent.this).searchOperation = null;
                        }
                    }
                };
            }
        }
        if(error == 1)
        {
            throw new BluetoothStateException("DiscoveryAgent.searchServices: выполняется другая операция.");
        }
        operation.start();
        return 0x21cd;
    }

    public RemoteDevice[] retrieveDevices(int option) {
        if(option < CACHED || option > PREKNOWN)
        {
            throw new IllegalArgumentException("DiscoveryAgent.retrieveDevices: аргумент option имеет недопустимое значение.");
        }
        return emptyRemoteDeviceList;
    }

    public String selectService(UUID uuid, int security, boolean master) throws BluetoothStateException {
        if(uuid == null)
        {
            throw new NullPointerException("DiscoveryAgent.selectService: аргумент uuid равен нулевой ссылке.");
        }
        if(security < ServiceRecord.NOAUTHENTICATE_NOENCRYPT || security > ServiceRecord.AUTHENTICATE_ENCRYPT)
        {
            throw new IllegalArgumentException("DiscoveryAgent.selectService: аргумент security имеет недопустимое значение.");
        }
        return null;
    }
}
