package com.wytehat.btlogger;

import android.os.ParcelUuid;
import java.util.List;
import java.util.Locale;

public final class BleFingerprintRegistry {
    public static final class Match {
        public final String uuid, label, vendor, category;
        Match(String uuid, String label, String vendor, String category) {
            this.uuid = uuid; this.label = label; this.vendor = vendor; this.category = category;
        }
    }

    private BleFingerprintRegistry() { }

    public static Match first(List<ParcelUuid> services) {
        if (services == null) return null;
        for (int i = 0; i < services.size(); i++) {
            Match match = lookup(shortUuid(services.get(i).toString()));
            if (match != null) return match;
        }
        return null;
    }

    public static Match lookup(String uuid) {
        String value = shortUuid(uuid);
        if ("FEED".equals(value) || "FEEC".equals(value) || "FD84".equals(value)) return m(value, "Tile tracker service", "Tile, Inc.", "Trackers / Tags");
        if ("FE8B".equals(value)) return m(value, "Apple Find My Network", "Apple, Inc.", "Trackers / Tags");
        if ("FD5B".equals(value)) return m(value, "Samsung SmartTag / Find Network", "Samsung Electronics", "Trackers / Tags");
        if ("FEAA".equals(value)) return m(value, "Eddystone beacon", "Google LLC", "Trackers / Tags");
        if ("FED8".equals(value)) return m(value, "Eddystone URL beacon", "Google LLC", "Trackers / Tags");
        if ("FE9A".equals(value)) return m(value, "Estimote location beacon", "Estimote, Inc.", "Trackers / Tags");
        if ("FE2C".equals(value)) return m(value, "Fast Pair service", "Google LLC", "Ecosystem / Pairing");
        if ("FE9F".equals(value) || "FEA0".equals(value)) return m(value, "Google member service", "Google LLC", "Ecosystem / Pairing");
        if ("FE40".equals(value)) return m(value, "Fast Pair network", "Google LLC", "Ecosystem / Pairing");
        if ("FED3".equals(value) || "FED4".equals(value)) return m(value, "Apple member service", "Apple, Inc.", "Ecosystem / Continuity");
        if ("FD59".equals(value) || "FD5A".equals(value) || "FD69".equals(value) || "FD6C".equals(value)) return m(value, "Samsung member service", "Samsung Electronics", "Ecosystem / Continuity");
        if ("FE33".equals(value)) return m(value, "CHIP / Matter protocol", "Connectivity Standards Alliance", "Smart Home");
        if ("FE65".equals(value)) return m(value, "CHIP / Matter setup", "Connectivity Standards Alliance", "Smart Home");
        if ("FE00".equals(value)) return m(value, "Amazon Echo / Sidewalk", "Amazon.com", "Smart Home");
        if ("FE50".equals(value)) return m(value, "Ring doorbell / camera", "Ring LLC (Amazon)", "Smart Home");
        if ("FEAF".equals(value) || "FEB0".equals(value)) return m(value, "Nest member service", "Nest Labs Inc.", "Smart Home");
        if ("FE24".equals(value)) return m(value, "August smart lock", "August Home Inc.", "Smart Home");
        if ("FE35".equals(value)) return m(value, "Hormann smart opener", "Hormann KG", "Smart Home");
        if ("FDC2".equals(value)) return m(value, "Baidu smart IoT", "Baidu", "Smart Home");
        if ("1815".equals(value)) return m(value, "Automation IO", null, "Smart Home");
        if ("FE95".equals(value)) return m(value, "Xiaomi member service", "Xiaomi Inc.", "Wearables");
        if ("FDB2".equals(value)) return m(value, "Fitbit BLE service", "Fitbit / Google", "Wearables");
        if ("FE08".equals(value)) return m(value, "Garmin fitness service", "Garmin International", "Wearables");
        if ("FED9".equals(value)) return m(value, "Pebble service", "Pebble Technology", "Wearables");
        if ("FE87".equals(value)) return m(value, "Meta / Oculus VR system", "Meta Platforms", "Wearables / VR");
        if ("180D".equals(value)) return m(value, "Heart Rate", null, "Wearables");
        if ("1814".equals(value)) return m(value, "Running Speed & Cadence", null, "Wearables");
        if ("1816".equals(value)) return m(value, "Cycling Speed & Cadence", null, "Wearables");
        if ("1818".equals(value)) return m(value, "Cycling Power", null, "Wearables");
        if ("1822".equals(value)) return m(value, "Pulse Oximeter", null, "Wearables");
        if ("1826".equals(value)) return m(value, "Fitness Machine", null, "Wearables");
        if ("FD6F".equals(value)) return m(value, "Exposure Notification", "Apple / Google", "Health");
        if ("FD87".equals(value)) return m(value, "Google Health & Medical", "Google LLC", "Health");
        if ("1808".equals(value)) return m(value, "Glucose Service", null, "Health");
        if ("1809".equals(value)) return m(value, "Health Thermometer", null, "Health");
        if ("1810".equals(value)) return m(value, "Blood Pressure", null, "Health");
        if ("181B".equals(value)) return m(value, "Body Composition", null, "Health");
        if ("181C".equals(value)) return m(value, "User Data", null, "Health");
        if ("181D".equals(value)) return m(value, "Weight Scale", null, "Health");
        if ("183A".equals(value)) return m(value, "Insulin Delivery", null, "Health");
        if ("FEBE".equals(value)) return m(value, "Bose audio control", "Bose Corporation", "Audio");
        if ("FE21".equals(value)) return m(value, "Bose headphones service", "Bose Corporation", "Audio");
        if ("FDD2".equals(value)) return m(value, "Bose smart audio", "Bose Corporation", "Audio");
        if ("FD82".equals(value)) return m(value, "Sony wireless audio", "Sony Corporation", "Audio");
        if ("FD83".equals(value)) return m(value, "Sony Headphones Connect", "Sony Corporation", "Audio");
        if ("FE3B".equals(value)) return m(value, "Dolby audio service", "Dolby Laboratories", "Audio");
        if ("FDA5".equals(value)) return m(value, "Nvidia Shield controller", "NVIDIA Corporation", "Gaming");
        if ("FDE2".equals(value)) return m(value, "Razer gaming peripheral", "Razer Inc.", "Gaming");
        if ("FE96".equals(value) || "FE97".equals(value)) return m(value, "Tesla vehicle service", "Tesla Motors", "Vehicles");
        if ("FEA5".equals(value) || "FEA6".equals(value)) return m(value, "GoPro service", "GoPro, Inc.", "Cameras");
        if ("FEB2".equals(value)) return m(value, "Microsoft member service", "Microsoft Corporation", "Computers");
        if ("1812".equals(value)) return m(value, "HID / Input", null, "Computers");
        if ("FE79".equals(value)) return m(value, "Zebra member service", "Zebra Technologies", "Enterprise / Scanners");
        if ("FD9A".equals(value) || "FD9B".equals(value)) return m(value, "Yubikey authentication", "Yubico AB", "Security / Auth");
        if ("181E".equals(value)) return m(value, "Bond Management", null, "Security / Auth");
        if ("FEE4".equals(value) || "FEE5".equals(value) || "FE59".equals(value)) return m(value, "Nordic device / DFU service", "Nordic Semiconductor ASA", "Development / Firmware");
        if ("FEE9".equals(value)) return m(value, "Quintic member service", "Quintic Corp.", "Development / Firmware");
        if ("FEBB".equals(value)) return m(value, "Adafruit file transfer", "Adafruit Industries", "Development / Firmware");
        if ("FEB3".equals(value)) return m(value, "Alibaba / Taobao IoT", "Alibaba Group", "Development / Firmware");
        if ("FE01".equals(value)) return m(value, "Duracell smart power", "Duracell", "Hardware");
        if ("1800".equals(value)) return m(value, "Generic Access", null, "Core / System");
        if ("1801".equals(value)) return m(value, "Generic Attribute", null, "Core / System");
        if ("1802".equals(value)) return m(value, "Immediate Alert", null, "Core / System");
        if ("1803".equals(value)) return m(value, "Link Loss", null, "Core / System");
        if ("1804".equals(value)) return m(value, "Tx Power Level", null, "Core / System");
        if ("1805".equals(value)) return m(value, "Current Time", null, "Core / System");
        if ("1806".equals(value)) return m(value, "Reference Time Update", null, "Core / System");
        if ("1807".equals(value)) return m(value, "Next DST Change", null, "Core / System");
        if ("180A".equals(value)) return m(value, "Device Information", null, "Core / System");
        if ("180F".equals(value)) return m(value, "Battery Service", null, "Core / System");
        if ("1811".equals(value)) return m(value, "Alert Notification", null, "Core / System");
        if ("1813".equals(value)) return m(value, "Scan Parameters", null, "Core / System");
        if ("1819".equals(value)) return m(value, "Location & Navigation", null, "Core / System");
        if ("181A".equals(value)) return m(value, "Environmental Sensing", null, "Sensors");
        if ("183B".equals(value)) return m(value, "Binary Sensor", null, "Sensors");
        if ("1820".equals(value)) return m(value, "IP Support Protocol", null, "Networking");
        if ("1821".equals(value)) return m(value, "Indoor Positioning", null, "Core / System");
        if ("1823".equals(value)) return m(value, "HTTP Proxy", null, "Networking");
        if ("1824".equals(value)) return m(value, "Transport Discovery", null, "Networking");
        if ("1825".equals(value)) return m(value, "Object Transfer", null, "Networking");
        if ("1827".equals(value)) return m(value, "Mesh Provisioning", null, "Networking");
        if ("1828".equals(value)) return m(value, "Mesh Proxy", null, "Networking");
        return null;
    }

	public static String shortUuid(String raw) {
		if (raw == null) return "";
		String value = raw.replace("-", "").toUpperCase(Locale.US);
		if (value.length() == 32 && value.startsWith("0000") && value.endsWith("00001000800000805F9B34FB")) return value.substring(4, 8);
		return value.length() == 4 ? value : (value.length() >= 8 && value.startsWith("0000") ? value.substring(4, 8) : value);
	}
	
    private static Match m(String uuid, String label, String vendor, String category) {
        return new Match(uuid, label, vendor, category);
    }
}
