"""Check if a host is in the Google Chrome HSTS Preload list"""

import functools
import os
import typing

__version__ = "2021.12.1"
__checksum__ = "6783d781e3ec688d0394c8b70993af15e7e71acd6e5a5e28ce9b2e44e4f8ed3c"
__all__ = ["in_hsts_preload"]

# fmt: off
_GTLD_INCLUDE_SUBDOMAINS = {b'android', b'app', b'bank', b'boo', b'chrome', b'dad', b'day', b'dev', b'eat', b'esq', b'fly', b'foo', b'gle', b'gmail', b'google', b'hangout', b'ing', b'insurance', b'meet', b'meme', b'new', b'nexus', b'page', b'phd', b'play', b'prof', b'rsvp', b'search', b'youtube'}  # noqa: E501
_JUMPTABLE = [[(0, 11), (11, 10), (21, 9), (30, 61), (91, 26), (117, 12), None, (129, 19), (148, 22), (170, 7), (177, 20), (197, 18), None, (215, 29), (244, 45), (289, 7), (296, 9), (305, 36), (341, 16), (357, 10), (367, 28), None, (395, 54), (449, 8), (457, 18), (475, 19), (494, 13), (507, 14), (521, 14), None, None, (535, 33), (568, 20), (588, 35), (623, 14), (637, 24), (661, 9), (670, 9), (679, 25), (704, 27), (731, 8), (739, 13), None, None, (752, 17), (769, 6), (775, 26), (801, 10), (811, 5), (816, 19), (835, 14), (849, 11), (860, 12), (872, 27), None, (899, 24), (923, 11), (934, 7), (941, 29), (970, 18), (988, 27), (1015, 46), (1061, 25), (1086, 16), (1102, 8), (1110, 5), (1115, 22), (1137, 18), None, (1155, 36), (1191, 15), (1206, 8), (1214, 11), None, (1225, 5), (1230, 16), (1246, 14), (1260, 18), None, (1278, 20), (1298, 18), (1316, 48), (1364, 19), (1383, 12), (1395, 59), (1454, 14), (1468, 14), (1482, 20), None, (1502, 10), (1512, 13), (1525, 20), (1545, 19), None, (1564, 13), (1577, 19), (1596, 11), (1607, 4), (1611, 22), (1633, 10), (1643, 7), (1650, 14), (1664, 21), (1685, 11), (1696, 21), (1717, 12), (1729, 32), None, (1761, 10), (1771, 14), (1785, 19), (1804, 45), (1849, 15), None, (1864, 11), (1875, 23), (1898, 21), (1919, 26), (1945, 6), (1951, 6), (1957, 7), (1964, 5), (1969, 20), (1989, 23), (2012, 24), (2036, 17), (2053, 15), (2068, 19), (2087, 12), (2099, 61), (2160, 55), (2215, 12), (2227, 23), (2250, 16), (2266, 38), (2304, 6), (2310, 12), (2322, 44), (2366, 6), (2372, 41), (2413, 13), (2426, 23), (2449, 36), (2485, 20), (2505, 8), (2513, 15), (2528, 12), (2540, 19), (2559, 25), (2584, 15), None, (2599, 35), (2634, 21), (2655, 17), (2672, 19), (2691, 26), (2717, 5), (2722, 37), (2759, 39), (2798, 16), (2814, 10), (2824, 17), (2841, 23), (2864, 14), (2878, 17), (2895, 8), (2903, 8), (2911, 7), (2918, 29), (2947, 6), (2953, 18), (2971, 32), (3003, 20), (3023, 17), (3040, 24), (3064, 12), (3076, 40), (3116, 40), (3156, 12), (3168, 48), (3216, 32), (3248, 17), None, (3265, 8), (3273, 25), (3298, 19), (3317, 6), (3323, 23), None, (3346, 30), (3376, 33), (3409, 14), (3423, 16), (3439, 27), None, (3466, 30), (3496, 41), (3537, 50), (3587, 15), (3602, 20), (3622, 25), (3647, 21), (3668, 32), (3700, 24), (3724, 20), (3744, 17), (3761, 60), (3821, 19), (3840, 9), (3849, 12), (3861, 12), (3873, 11), (3884, 10), (3894, 48), (3942, 42), None, (3984, 25), (4009, 28), None, (4037, 8), (4045, 8), (4053, 7), None, (4060, 25), (4085, 17), None, (4102, 21), (4123, 35), (4158, 21), (4179, 10), (4189, 41), (4230, 20), (4250, 31), (4281, 23), (4304, 19), (4323, 12), (4335, 5), (4340, 30), (4370, 29), (4399, 14), (4413, 14), (4427, 47), (4474, 52), None, None, (4526, 51), (4577, 42), None, (4619, 14), None, (4633, 15), (4648, 8), (4656, 21), (4677, 6), (4683, 16), (4699, 17)], [(4716, 8623), (13339, 9382), (22721, 9563), (32284, 8337), (40621, 8707), (49328, 8307), (57635, 9286), (66921, 8259), (75180, 9355), (84535, 8599), (93134, 9591), (102725, 8458), (111183, 9070), (120253, 10314), (130567, 8811), (139378, 9225), (148603, 9633), (158236, 8906), (167142, 8909), (176051, 8387), (184438, 9444), (193882, 9085), (202967, 9137), (212104, 8625), (220729, 9156), (229885, 8763), (238648, 9193), (247841, 9169), (257010, 8341), (265351, 8972), (274323, 9300), (283623, 8751), (292374, 8856), (301230, 8957), (310187, 8093), (318280, 8924), (327204, 8914), (336118, 9730), (345848, 9237), (355085, 9186), (364271, 9711), (373982, 8447), (382429, 8492), (390921, 8632), (399553, 8914), (408467, 8828), (417295, 8801), (426096, 9948), (436044, 8659), (444703, 8184), (452887, 8709), (461596, 9200), (470796, 9138), (479934, 9070), (489004, 9415), (498419, 8952), (507371, 9196), (516567, 8919), (525486, 9141), (534627, 7823), (542450, 8872), (551322, 9088), (560410, 8746), (569156, 9245), (578401, 9213), (587614, 9314), (596928, 8545), (605473, 9638), (615111, 9398), (624509, 8865), (633374, 9133), (642507, 8543), (651050, 7901), (658951, 9318), (668269, 8972), (677241, 9580), (686821, 8221), (695042, 9609), (704651, 9186), (713837, 8481), (722318, 9253), (731571, 7877), (739448, 8623), (748071, 9247), (757318, 8643), (765961, 9118), (775079, 9736), (784815, 8821), (793636, 9181), (802817, 9075), (811892, 9945), (821837, 8453), (830290, 8927), (839217, 8880), (848097, 8865), (856962, 9445), (866407, 9192), (875599, 8837), (884436, 8643), (893079, 8411), (901490, 8489), (909979, 9122), (919101, 8911), (928012, 8774), (936786, 8677), (945463, 9472), (954935, 9445), (964380, 9488), (973868, 10054), (983922, 9267), (993189, 9381), (1002570, 9243), (1011813, 8904), (1020717, 8783), (1029500, 9246), (1038746, 9020), (1047766, 8859), (1056625, 9031), (1065656, 8720), (1074376, 9722), (1084098, 9571), (1093669, 9355), (1103024, 9101), (1112125, 9278), (1121403, 9930), (1131333, 8742), (1140075, 8369), (1148444, 9587), (1158031, 8971), (1167002, 10571), (1177573, 9565), (1187138, 8679), (1195817, 9168), (1204985, 8770), (1213755, 8716), (1222471, 9272), (1231743, 8358), (1240101, 9684), (1249785, 8608), (1258393, 8705), (1267098, 9228), (1276326, 9356), (1285682, 8322), (1294004, 8641), (1302645, 9435), (1312080, 8657), (1320737, 8886), (1329623, 8894), (1338517, 8476), (1346993, 9348), (1356341, 9174), (1365515, 9124), (1374639, 9205), (1383844, 8660), (1392504, 9060), (1401564, 9373), (1410937, 8631), (1419568, 9059), (1428627, 8643), (1437270, 8129), (1445399, 8033), (1453432, 9076), (1462508, 9664), (1472172, 8511), (1480683, 8836), (1489519, 9812), (1499331, 8969), (1508300, 8504), (1516804, 9408), (1526212, 8929), (1535141, 8138), (1543279, 8861), (1552140, 10450), (1562590, 8445), (1571035, 8442), (1579477, 9589), (1589066, 8913), (1597979, 9330), (1607309, 8884), (1616193, 8645), (1624838, 11271), (1636109, 9113), (1645222, 8945), (1654167, 9323), (1663490, 9982), (1673472, 9866), (1683338, 8242), (1691580, 9278), (1700858, 8579), (1709437, 8886), (1718323, 9713), (1728036, 8509), (1736545, 9254), (1745799, 9070), (1754869, 8968), (1763837, 8917), (1772754, 8714), (1781468, 8475), (1789943, 8948), (1798891, 8768), (1807659, 9201), (1816860, 8578), (1825438, 9814), (1835252, 8940), (1844192, 9673), (1853865, 9385), (1863250, 8111), (1871361, 9237), (1880598, 8782), (1889380, 9112), (1898492, 9134), (1907626, 9338), (1916964, 8989), (1925953, 9317), (1935270, 9203), (1944473, 8976), (1953449, 8827), (1962276, 8813), (1971089, 9079), (1980168, 9476), (1989644, 8992), (1998636, 8261), (2006897, 9908), (2016805, 8948), (2025753, 8871), (2034624, 8639), (2043263, 8790), (2052053, 8336), (2060389, 9541), (2069930, 9065), (2078995, 9842), (2088837, 9003), (2097840, 8530), (2106370, 9555), (2115925, 8737), (2124662, 9848), (2134510, 8595), (2143105, 8555), (2151660, 7913), (2159573, 9691), (2169264, 9200), (2178464, 9512), (2187976, 8653), (2196629, 9206), (2205835, 8928), (2214763, 9436), (2224199, 8740), (2232939, 8169), (2241108, 8861), (2249969, 8362), (2258331, 9202), (2267533, 9531), (2277064, 9441), (2286505, 8877), (2295382, 8877), (2304259, 9092)], [(2313351, 1014), (2314365, 825), (2315190, 871), (2316061, 1089), (2317150, 734), (2317884, 908), (2318792, 741), (2319533, 1047), (2320580, 800), (2321380, 881), (2322261, 656), (2322917, 713), (2323630, 892), (2324522, 948), (2325470, 1090), (2326560, 1083), (2327643, 1343), (2328986, 744), (2329730, 1067), (2330797, 887), (2331684, 985), (2332669, 967), (2333636, 1063), (2334699, 898), (2335597, 921), (2336518, 766), (2337284, 1167), (2338451, 1414), (2339865, 894), (2340759, 984), (2341743, 1095), (2342838, 932), (2343770, 737), (2344507, 863), (2345370, 1116), (2346486, 962), (2347448, 874), (2348322, 943), (2349265, 866), (2350131, 1237), (2351368, 775), (2352143, 1131), (2353274, 944), (2354218, 852), (2355070, 891), (2355961, 617), (2356578, 1108), (2357686, 1158), (2358844, 919), (2359763, 675), (2360438, 939), (2361377, 778), (2362155, 936), (2363091, 1145), (2364236, 1164), (2365400, 639), (2366039, 808), (2366847, 726), (2367573, 783), (2368356, 951), (2369307, 994), (2370301, 951), (2371252, 1189), (2372441, 1114), (2373555, 815), (2374370, 885), (2375255, 856), (2376111, 564), (2376675, 769), (2377444, 767), (2378211, 867), (2379078, 1040), (2380118, 732), (2380850, 939), (2381789, 749), (2382538, 851), (2383389, 759), (2384148, 862), (2385010, 869), (2385879, 602), (2386481, 948), (2387429, 762), (2388191, 1068), (2389259, 778), (2390037, 934), (2390971, 691), (2391662, 876), (2392538, 923), (2393461, 984), (2394445, 924), (2395369, 1177), (2396546, 1324), (2397870, 993), (2398863, 919), (2399782, 915), (2400697, 601), (2401298, 1077), (2402375, 985), (2403360, 686), (2404046, 799), (2404845, 895), (2405740, 1090), (2406830, 988), (2407818, 648), (2408466, 771), (2409237, 960), (2410197, 618), (2410815, 628), (2411443, 1180), (2412623, 1113), (2413736, 882), (2414618, 899), (2415517, 830), (2416347, 861), (2417208, 952), (2418160, 891), (2419051, 746), (2419797, 739), (2420536, 844), (2421380, 781), (2422161, 1170), (2423331, 849), (2424180, 953), (2425133, 604), (2425737, 868), (2426605, 1023), (2427628, 911), (2428539, 1104), (2429643, 818), (2430461, 1185), (2431646, 984), (2432630, 773), (2433403, 1056), (2434459, 824), (2435283, 1059), (2436342, 872), (2437214, 832), (2438046, 776), (2438822, 885), (2439707, 765), (2440472, 801), (2441273, 841), (2442114, 841), (2442955, 669), (2443624, 676), (2444300, 637), (2444937, 785), (2445722, 759), (2446481, 901), (2447382, 816), (2448198, 871), (2449069, 645), (2449714, 685), (2450399, 995), (2451394, 858), (2452252, 801), (2453053, 880), (2453933, 1101), (2455034, 961), (2455995, 743), (2456738, 1115), (2457853, 902), (2458755, 735), (2459490, 922), (2460412, 1189), (2461601, 771), (2462372, 829), (2463201, 814), (2464015, 822), (2464837, 850), (2465687, 954), (2466641, 731), (2467372, 1093), (2468465, 909), (2469374, 1010), (2470384, 1049), (2471433, 821), (2472254, 683), (2472937, 826), (2473763, 810), (2474573, 2043), (2476616, 743), (2477359, 879), (2478238, 819), (2479057, 1189), (2480246, 871), (2481117, 915), (2482032, 754), (2482786, 704), (2483490, 1046), (2484536, 727), (2485263, 691), (2485954, 933), (2486887, 930), (2487817, 1143), (2488960, 887), (2489847, 890), (2490737, 830), (2491567, 940), (2492507, 857), (2493364, 957), (2494321, 868), (2495189, 984), (2496173, 818), (2496991, 834), (2497825, 773), (2498598, 995), (2499593, 1015), (2500608, 826), (2501434, 1099), (2502533, 844), (2503377, 961), (2504338, 1057), (2505395, 1184), (2506579, 996), (2507575, 863), (2508438, 1028), (2509466, 836), (2510302, 633), (2510935, 530), (2511465, 950), (2512415, 935), (2513350, 695), (2514045, 1217), (2515262, 686), (2515948, 848), (2516796, 1011), (2517807, 1007), (2518814, 1015), (2519829, 832), (2520661, 1035), (2521696, 805), (2522501, 1001), (2523502, 731), (2524233, 742), (2524975, 686), (2525661, 730), (2526391, 486), (2526877, 917), (2527794, 1105), (2528899, 918), (2529817, 777), (2530594, 762), (2531356, 727), (2532083, 1053), (2533136, 667), (2533803, 655), (2534458, 1007), (2535465, 536), (2536001, 1102), (2537103, 2533), (2539636, 769), (2540405, 855), (2541260, 1052), (2542312, 1170), (2543482, 516)], [(2543998, 48), None, (2544046, 35), (2544081, 42), None, None, None, None, None, None, None, None, None, None, None, None, None, (2544123, 42), None, (2544165, 25), (2544190, 44), (2544234, 22), (2544256, 18), None, None, None, None, (2544274, 26), None, None, None, None, (2544300, 21), (2544321, 25), None, None, (2544346, 26), None, None, None, None, (2544372, 71), (2544443, 21), (2544464, 23), None, None, None, None, (2544487, 48), None, None, None, None, None, (2544535, 31), None, None, None, None, (2544566, 42), None, (2544608, 22), None, (2544630, 21), None, (2544651, 26), (2544677, 42), None, None, (2544719, 77), (2544796, 27), None, None, None, None, (2544823, 21), (2544844, 21), None, None, (2544865, 34), (2544899, 42), None, None, None, (2544941, 25), None, None, (2544966, 21), None, None, None, None, None, (2544987, 24), (2545011, 21), None, None, (2545032, 26), None, (2545058, 18), None, (2545076, 54), None, None, None, None, None, None, (2545130, 26), None, None, None, (2545156, 20), None, None, (2545176, 64), (2545240, 42), (2545282, 17), (2545299, 17), (2545316, 26), None, (2545342, 26), None, None, None, (2545368, 26), (2545394, 20), (2545414, 26), None, (2545440, 42), (2545482, 63), None, None, None, (2545545, 40), (2545585, 48), None, None, None, (2545633, 47), None, None, None, None, None, None, None, (2545680, 42), None, (2545722, 80), None, (2545802, 9), None, (2545811, 21), (2545832, 42), None, None, (2545874, 65), (2545939, 82), (2546021, 21), None, (2546042, 72), None, None, (2546114, 24), (2546138, 21), None, None, None, None, None, (2546159, 42), (2546201, 21), (2546222, 21), None, (2546243, 42), (2546285, 25), None, (2546310, 38), (2546348, 21), (2546369, 56), None, None, (2546425, 21), (2546446, 19), (2546465, 26), None, (2546491, 16), None, (2546507, 21), None, None, (2546528, 38), None, (2546566, 22), (2546588, 21), (2546609, 21), (2546630, 21), None, (2546651, 63), None, (2546714, 21), (2546735, 42), None, (2546777, 17), None, None, None, None, (2546794, 21), (2546815, 21), None, None, (2546836, 21), None, None, (2546857, 21), None, (2546878, 26), None, (2546904, 50), (2546954, 22), None, None, (2546976, 50), (2547026, 26), (2547052, 21), (2547073, 21), (2547094, 19), None, (2547113, 35), (2547148, 26), (2547174, 23), (2547197, 39), (2547236, 42), None, None, None, None, None, None, (2547278, 21), None, None, None, (2547299, 21), None, None, (2547320, 90), None, (2547410, 239), (2547649, 38), None, None, None, None]]  # noqa: E501
_CRC8_TABLE = [
    0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
    0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
    0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
    0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
    0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
    0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
    0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
    0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
    0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
    0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
    0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
    0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
    0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
    0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
    0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
    0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
    0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
    0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
    0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
    0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
    0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
    0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
    0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
    0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
    0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
    0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
    0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
    0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
    0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
    0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
    0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
    0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
]
# fmt: on

_IS_LEAF = 0x80
_INCLUDE_SUBDOMAINS = 0x40


try:
    from importlib.resources import open_binary

    def open_pkg_binary(path: str) -> typing.BinaryIO:
        return open_binary("hstspreload", path)


except ImportError:

    def open_pkg_binary(path: str) -> typing.BinaryIO:
        return open(
            os.path.join(os.path.dirname(os.path.abspath(__file__)), path),
            "rb",
        )


@functools.lru_cache(maxsize=1024)
def in_hsts_preload(host: typing.AnyStr) -> bool:
    """Determines if an IDNA-encoded host is on the HSTS preload list"""

    if isinstance(host, str):
        host = host.encode("ascii")
    labels = host.lower().split(b".")

    # Fast-branch for gTLDs that are registered to preload all sub-domains.
    if labels[-1] in _GTLD_INCLUDE_SUBDOMAINS:
        return True

    with open_pkg_binary("hstspreload.bin") as f:
        for layer, label in enumerate(labels[::-1]):
            # None of our layers are greater than 4 deep.
            if layer > 3:
                return False

            # Read the jump table for the layer and label
            jump_info = _JUMPTABLE[layer][_crc8(label)]
            if jump_info is None:
                # No entry: host is not preloaded
                return False

            # Read the set of entries for that layer and label
            f.seek(jump_info[0])
            data = bytearray(jump_info[1])
            f.readinto(data)

            for is_leaf, include_subdomains, ent_label in _iter_entries(data):
                # We found a potential leaf
                if is_leaf:
                    if ent_label == host:
                        return True
                    if include_subdomains and host.endswith(b"." + ent_label):
                        return True

                # Continue traversing as we're not at a leaf.
                elif label == ent_label:
                    break
            else:
                return False
    return False


def _iter_entries(data: bytes) -> typing.Iterable[typing.Tuple[int, int, bytes]]:
    while data:
        flags = data[0]
        size = data[1]
        label = bytes(data[2 : 2 + size])
        yield (flags & _IS_LEAF, flags & _INCLUDE_SUBDOMAINS, label)
        data = data[2 + size :]


def _crc8(value: bytes) -> int:
    # CRC8 reference implementation: https://github.com/niccokunzmann/crc8
    checksum = 0x00
    for byte in value:
        checksum = _CRC8_TABLE[checksum ^ byte]
    return checksum
