<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Util;

/**
 * Get information about countries.
 *
 * This class is used to get the continent of countries.
 */
class CountriesInfo
{
    private static $cacheCountriesCodeByContinent;

    private static ?array $preparedData = null;

    /**
     * get the information about country in arrays where :.
     *
     * - key 0 = continent
     * - key 1 = country code, in 2 letters
     * - key 2 = country code, in 3 letters
     * - key 3 = country number
     * - key 4 = country name, in english
     *
     * @return array an array of countries array
     */
    public static function getArrayCountriesData()
    {
        if (null === self::$preparedData) {
            $raw = self::getCountriesData();

            // parse data line by line
            $separator = "\r\n";
            $line = strtok($raw, $separator);

            while (false !== $line) {
                self::$preparedData[] = explode(' ', $line, 5);

                $line = strtok($separator);
            }

            return self::$preparedData;
        }

        return self::$preparedData;
    }

    public static function getContinentsCodes()
    {
        self::prepareCacheCountriesByContinent();

        return array_keys(self::$cacheCountriesCodeByContinent);
    }

    public static function getCountriesCodeByContinent($continent)
    {
        self::prepareCacheCountriesByContinent();

        if (\array_key_exists($continent, self::$cacheCountriesCodeByContinent)) {
            return self::$cacheCountriesCodeByContinent[$continent];
        }

        throw new \UnexpectedValueException(sprintf('The continent with prefix %s is unknown.', $continent));
    }

    public static function getCountriesData()
    {
        // this list is extracted by https://en.wikipedia.org/wiki/List_of_sovereign_states_and_dependent_territories_by_continent_%28data_file%29
        //
        // The columns are :
        // - continent code ;
        // - country code (two letters) ;
        // - country code (three letters) ;
        // - country number
        // - english name
        //
        // source :
        // Wikipedia contributors, "List of sovereign states and dependent territories by continent (data file),"
        // Wikipedia, The Free Encyclopedia, https://en.wikipedia.org/w/index.php?title=List_of_sovereign_states_and_dependent_territories_by_continent_(data_file)&oldid=688980440
        // (accessed January 2, 2016).
        return <<<'EOT'
            AS AF AFG 004 Afghanistan, Islamic Republic of
            EU AL ALB 008 Albania, Republic of
            AN AQ ATA 010 Antarctica (the territory South of 60 deg S)
            AF DZ DZA 012 Algeria, People's Democratic Republic of
            OC AS ASM 016 American Samoa
            EU AD AND 020 Andorra, Principality of
            AF AO AGO 024 Angola, Republic of
            NA AG ATG 028 Antigua and Barbuda
            EU AZ AZE 031 Azerbaijan, Republic of
            AS AZ AZE 031 Azerbaijan, Republic of
            SA AR ARG 032 Argentina, Argentine Republic
            OC AU AUS 036 Australia, Commonwealth of
            EU AT AUT 040 Austria, Republic of
            NA BS BHS 044 Bahamas, Commonwealth of the
            AS BH BHR 048 Bahrain, Kingdom of
            AS BD BGD 050 Bangladesh, People's Republic of
            EU AM ARM 051 Armenia, Republic of
            AS AM ARM 051 Armenia, Republic of
            NA BB BRB 052 Barbados
            EU BE BEL 056 Belgium, Kingdom of
            NA BM BMU 060 Bermuda
            AS BT BTN 064 Bhutan, Kingdom of
            SA BO BOL 068 Bolivia, Republic of
            EU BA BIH 070 Bosnia and Herzegovina
            AF BW BWA 072 Botswana, Republic of
            AN BV BVT 074 Bouvet Island (Bouvetoya)
            SA BR BRA 076 Brazil, Federative Republic of
            NA BZ BLZ 084 Belize
            AS IO IOT 086 British Indian Ocean Territory (Chagos Archipelago)
            OC SB SLB 090 Solomon Islands
            NA VG VGB 092 British Virgin Islands
            AS BN BRN 096 Brunei Darussalam
            EU BG BGR 100 Bulgaria, Republic of
            AS MM MMR 104 Myanmar, Union of
            AF BI BDI 108 Burundi, Republic of
            EU BY BLR 112 Belarus, Republic of
            AS KH KHM 116 Cambodia, Kingdom of
            AF CM CMR 120 Cameroon, Republic of
            NA CA CAN 124 Canada
            AF CV CPV 132 Cape Verde, Republic of
            NA KY CYM 136 Cayman Islands
            AF CF CAF 140 Central African Republic
            AS LK LKA 144 Sri Lanka, Democratic Socialist Republic of
            AF TD TCD 148 Chad, Republic of
            SA CL CHL 152 Chile, Republic of
            AS CN CHN 156 China, People's Republic of
            AS TW TWN 158 Taiwan
            AS CX CXR 162 Christmas Island
            AS CC CCK 166 Cocos (Keeling) Islands
            SA CO COL 170 Colombia, Republic of
            AF KM COM 174 Comoros, Union of the
            AF YT MYT 175 Mayotte
            AF CG COG 178 Congo, Republic of the
            AF CD COD 180 Congo, Democratic Republic of the
            OC CK COK 184 Cook Islands
            NA CR CRI 188 Costa Rica, Republic of
            EU HR HRV 191 Croatia, Republic of
            NA CU CUB 192 Cuba, Republic of
            EU CY CYP 196 Cyprus, Republic of
            AS CY CYP 196 Cyprus, Republic of
            EU CZ CZE 203 Czech Republic
            AF BJ BEN 204 Benin, Republic of
            EU DK DNK 208 Denmark, Kingdom of
            NA DM DMA 212 Dominica, Commonwealth of
            NA DO DOM 214 Dominican Republic
            SA EC ECU 218 Ecuador, Republic of
            NA SV SLV 222 El Salvador, Republic of
            AF GQ GNQ 226 Equatorial Guinea, Republic of
            AF ET ETH 231 Ethiopia, Federal Democratic Republic of
            AF ER ERI 232 Eritrea, State of
            EU EE EST 233 Estonia, Republic of
            EU FO FRO 234 Faroe Islands
            SA FK FLK 238 Falkland Islands (Malvinas)
            AN GS SGS 239 South Georgia and the South Sandwich Islands
            OC FJ FJI 242 Fiji, Republic of the Fiji Islands
            EU FI FIN 246 Finland, Republic of
            EU AX ALA 248 Åland Islands
            EU FR FRA 250 France, French Republic
            SA GF GUF 254 French Guiana
            OC PF PYF 258 French Polynesia
            AN TF ATF 260 French Southern Territories
            AF DJ DJI 262 Djibouti, Republic of
            AF GA GAB 266 Gabon, Gabonese Republic
            EU GE GEO 268 Georgia
            AS GE GEO 268 Georgia
            AF GM GMB 270 Gambia, Republic of the
            AS PS PSE 275 Palestinian Territory, Occupied
            EU DE DEU 276 Germany, Federal Republic of
            AF GH GHA 288 Ghana, Republic of
            EU GI GIB 292 Gibraltar
            OC KI KIR 296 Kiribati, Republic of
            EU GR GRC 300 Greece, Hellenic Republic
            NA GL GRL 304 Greenland
            NA GD GRD 308 Grenada
            NA GP GLP 312 Guadeloupe
            OC GU GUM 316 Guam
            NA GT GTM 320 Guatemala, Republic of
            AF GN GIN 324 Guinea, Republic of
            SA GY GUY 328 Guyana, Co-operative Republic of
            NA HT HTI 332 Haiti, Republic of
            AN HM HMD 334 Heard Island and McDonald Islands
            EU VA VAT 336 Holy See (Vatican City State)
            NA HN HND 340 Honduras, Republic of
            AS HK HKG 344 Hong Kong, Special Administrative Region of China
            EU HU HUN 348 Hungary, Republic of
            EU IS ISL 352 Iceland, Republic of
            AS IN IND 356 India, Republic of
            AS ID IDN 360 Indonesia, Republic of
            AS IR IRN 364 Iran, Islamic Republic of
            AS IQ IRQ 368 Iraq, Republic of
            EU IE IRL 372 Ireland
            AS IL ISR 376 Israel, State of
            EU IT ITA 380 Italy, Italian Republic
            AF CI CIV 384 Cote d'Ivoire, Republic of
            NA JM JAM 388 Jamaica
            AS JP JPN 392 Japan
            EU KZ KAZ 398 Kazakhstan, Republic of
            AS KZ KAZ 398 Kazakhstan, Republic of
            AS JO JOR 400 Jordan, Hashemite Kingdom of
            AF KE KEN 404 Kenya, Republic of
            AS KP PRK 408 Korea, Democratic People's Republic of
            AS KR KOR 410 Korea, Republic of
            AS KW KWT 414 Kuwait, State of
            AS KG KGZ 417 Kyrgyz Republic
            AS LA LAO 418 Lao People's Democratic Republic
            AS LB LBN 422 Lebanon, Lebanese Republic
            AF LS LSO 426 Lesotho, Kingdom of
            EU LV LVA 428 Latvia, Republic of
            AF LR LBR 430 Liberia, Republic of
            AF LY LBY 434 Libyan Arab Jamahiriya
            EU LI LIE 438 Liechtenstein, Principality of
            EU LT LTU 440 Lithuania, Republic of
            EU LU LUX 442 Luxembourg, Grand Duchy of
            AS MO MAC 446 Macao, Special Administrative Region of China
            AF MG MDG 450 Madagascar, Republic of
            AF MW MWI 454 Malawi, Republic of
            AS MY MYS 458 Malaysia
            AS MV MDV 462 Maldives, Republic of
            AF ML MLI 466 Mali, Republic of
            EU MT MLT 470 Malta, Republic of
            NA MQ MTQ 474 Martinique
            AF MR MRT 478 Mauritania, Islamic Republic of
            AF MU MUS 480 Mauritius, Republic of
            NA MX MEX 484 Mexico, United Mexican States
            EU MC MCO 492 Monaco, Principality of
            AS MN MNG 496 Mongolia
            EU MD MDA 498 Moldova, Republic of
            EU ME MNE 499 Montenegro, Republic of
            NA MS MSR 500 Montserrat
            AF MA MAR 504 Morocco, Kingdom of
            AF MZ MOZ 508 Mozambique, Republic of
            AS OM OMN 512 Oman, Sultanate of
            AF NA NAM 516 Namibia, Republic of
            OC NR NRU 520 Nauru, Republic of
            AS NP NPL 524 Nepal, State of
            EU NL NLD 528 Netherlands, Kingdom of the
            NA AN ANT 530 Netherlands Antilles
            NA CW CUW 531 Curaçao
            NA AW ABW 533 Aruba
            NA SX SXM 534 Sint Maarten (Netherlands)
            NA BQ BES 535 Bonaire, Sint Eustatius and Saba
            OC NC NCL 540 New Caledonia
            OC VU VUT 548 Vanuatu, Republic of
            OC NZ NZL 554 New Zealand
            NA NI NIC 558 Nicaragua, Republic of
            AF NE NER 562 Niger, Republic of
            AF NG NGA 566 Nigeria, Federal Republic of
            OC NU NIU 570 Niue
            OC NF NFK 574 Norfolk Island
            EU NO NOR 578 Norway, Kingdom of
            OC MP MNP 580 Northern Mariana Islands, Commonwealth of the
            OC UM UMI 581 United States Minor Outlying Islands
            NA UM UMI 581 United States Minor Outlying Islands
            OC FM FSM 583 Micronesia, Federated States of
            OC MH MHL 584 Marshall Islands, Republic of the
            OC PW PLW 585 Palau, Republic of
            AS PK PAK 586 Pakistan, Islamic Republic of
            NA PA PAN 591 Panama, Republic of
            OC PG PNG 598 Papua New Guinea, Independent State of
            SA PY PRY 600 Paraguay, Republic of
            SA PE PER 604 Peru, Republic of
            AS PH PHL 608 Philippines, Republic of the
            OC PN PCN 612 Pitcairn Islands
            EU PL POL 616 Poland, Republic of
            EU PT PRT 620 Portugal, Portuguese Republic
            AF GW GNB 624 Guinea-Bissau, Republic of
            AS TL TLS 626 Timor-Leste, Democratic Republic of
            NA PR PRI 630 Puerto Rico, Commonwealth of
            AS QA QAT 634 Qatar, State of
            AF RE REU 638 Reunion
            EU RO ROU 642 Romania
            EU RU RUS 643 Russian Federation
            AS RU RUS 643 Russian Federation
            AF RW RWA 646 Rwanda, Republic of
            NA BL BLM 652 Saint Barthelemy
            AF SH SHN 654 Saint Helena
            NA KN KNA 659 Saint Kitts and Nevis, Federation of
            NA AI AIA 660 Anguilla
            NA LC LCA 662 Saint Lucia
            NA MF MAF 663 Saint Martin
            NA PM SPM 666 Saint Pierre and Miquelon
            NA VC VCT 670 Saint Vincent and the Grenadines
            EU SM SMR 674 San Marino, Republic of
            AF ST STP 678 Sao Tome and Principe, Democratic Republic of
            AS SA SAU 682 Saudi Arabia, Kingdom of
            AF SN SEN 686 Senegal, Republic of
            EU RS SRB 688 Serbia, Republic of
            AF SC SYC 690 Seychelles, Republic of
            AF SL SLE 694 Sierra Leone, Republic of
            AS SG SGP 702 Singapore, Republic of
            EU SK SVK 703 Slovakia (Slovak Republic)
            AS VN VNM 704 Vietnam, Socialist Republic of
            EU SI SVN 705 Slovenia, Republic of
            AF SO SOM 706 Somalia, Somali Republic
            AF ZA ZAF 710 South Africa, Republic of
            AF ZW ZWE 716 Zimbabwe, Republic of
            EU ES ESP 724 Spain, Kingdom of
            AF SS SSD 728 South Sudan
            AF EH ESH 732 Western Sahara
            AF SD SDN 736 Sudan, Republic of
            SA SR SUR 740 Suriname, Republic of
            EU SJ SJM 744 Svalbard & Jan Mayen Islands
            AF SZ SWZ 748 Swaziland, Kingdom of
            EU SE SWE 752 Sweden, Kingdom of
            EU CH CHE 756 Switzerland, Swiss Confederation
            AS SY SYR 760 Syrian Arab Republic
            AS TJ TJK 762 Tajikistan, Republic of
            AS TH THA 764 Thailand, Kingdom of
            AF TG TGO 768 Togo, Togolese Republic
            OC TK TKL 772 Tokelau
            OC TO TON 776 Tonga, Kingdom of
            NA TT TTO 780 Trinidad and Tobago, Republic of
            AS AE ARE 784 United Arab Emirates
            AF TN TUN 788 Tunisia, Tunisian Republic
            EU TR TUR 792 Turkey, Republic of
            AS TR TUR 792 Turkey, Republic of
            AS TM TKM 795 Turkmenistan
            NA TC TCA 796 Turks and Caicos Islands
            OC TV TUV 798 Tuvalu
            AF UG UGA 800 Uganda, Republic of
            EU UA UKR 804 Ukraine
            EU MK MKD 807 Macedonia, The Republic of
            AF EG EGY 818 Egypt, Arab Republic of
            EU GB GBR 826 United Kingdom of Great Britain & Northern Ireland
            EU GG GGY 831 Guernsey, Bailiwick of
            EU JE JEY 832 Jersey, Bailiwick of
            EU IM IMN 833 Isle of Man
            AF TZ TZA 834 Tanzania, United Republic of
            NA US USA 840 United States of America
            NA VI VIR 850 United States Virgin Islands
            AF BF BFA 854 Burkina Faso
            SA UY URY 858 Uruguay, Eastern Republic of
            AS UZ UZB 860 Uzbekistan, Republic of
            SA VE VEN 862 Venezuela, Bolivarian Republic of
            OC WF WLF 876 Wallis and Futuna
            OC WS WSM 882 Samoa, Independent State of
            AS YE YEM 887 Yemen
            AF ZM ZMB 894 Zambia, Republic of
            OC XX null null Disputed Territory
            AS XE null null Iraq-Saudi Arabia Neutral Zone
            AS XD null null United Nations Neutral Zone
            AS XS null null Spratly Islands
            EOT;
    }

    private static function prepareCacheCountriesByContinent()
    {
        if (null === self::$cacheCountriesCodeByContinent) {
            $data = self::getArrayCountriesData();

            array_walk($data, static function ($item, $key) {
                self::$cacheCountriesCodeByContinent[$item[0]][] = $item[1];
            });
        }
    }
}
