export const R_URL_REQUIRES_PROTOCOL = /^https?:\/\/[^/\s]+(\/.*)?$/;

// matches hostname or *.wildcard
export const R_HOST = /^(\*\.)?[\w.-]+$/;

export const R_IPV4 = /^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$/;

export const R_IPV6 =
    /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;

export const R_CIDR =
    /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/;

export const R_MAC =
    /^((([a-fA-F0-9][a-fA-F0-9]+[-:]){5})([a-fA-F0-9]{2})$)|^((([a-fA-F0-9][a-fA-F0-9]+[-:]){7})([a-fA-F0-9]{2})$)|^([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]+[.]){2}([a-fA-F0-9]{4})$|^([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]+[.]){3}([a-fA-F0-9]{4})$/;
export const R_MAC_WITHOUT_COLON = /^([a-fA-F0-9]{2}){5}([a-fA-F0-9]{2})$|^([a-fA-F0-9]{2}){7}([a-fA-F0-9]{2})$/;

export const R_CIDR_IPV6 =
    /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$/;

export const R_DOMAIN = /^([a-zA-Z0-9][a-zA-Z0-9-_]*\.)*[a-zA-Z0-9]*[a-zA-Z0-9-_]*[[a-zA-Z0-9]+$/;

export const R_PATH_LAST_PART = /\/[^/]*$/;

// eslint-disable-next-line no-control-regex
export const R_UNIX_ABSOLUTE_PATH = /^(\/[^/\x00]+)+$/;

// eslint-disable-next-line no-control-regex
export const R_WIN_ABSOLUTE_PATH = /^([a-zA-Z]:)?(\\|\/)(?:[^\\/:*?"<>|\x00]+\\)*[^\\/:*?"<>|\x00]*$/;

export const R_CLIENT_ID = /^[a-z0-9-]{1,63}$/;

export const R_IPV4_SUBNET = /^([0-9]|[1-2][0-9]|3[0-2])?$/;

export const R_IPV6_SUBNET = /^([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])?$/;

export const MIN_PASSWORD_LENGTH = 8;
export const MAX_PASSWORD_LENGTH = 72;

export const HTML_PAGES = {
    INSTALL: '/install.html',
    LOGIN: '/login.html',
    MAIN: '/',
};

export const STATS_NAMES = {
    avg_processing_time: 'average_processing_time',
    blocked_filtering: 'Blocked by filters',
    dns_queries: 'DNS queries',
    replaced_parental: 'stats_adult',
    replaced_safebrowsing: 'stats_malware_phishing',
    replaced_safesearch: 'enforced_save_search',
};

export const STATUS_COLORS = {
    blue: '#467fcf',
    red: '#cd201f',
    green: '#5eba00',
    yellow: '#f1c40f',
};

export const REPOSITORY = {
    URL: 'https://github.com/AdguardTeam/AdGuardHome',
    TRACKERS_DB: 'https://github.com/AdguardTeam/AdGuardHome/tree/master/client/src/helpers/trackers/trackers.json',
    ISSUES: 'https://github.com/AdguardTeam/AdGuardHome/issues/new/choose',
};

export const CLIENT_ID_LINK = 'https://github.com/AdguardTeam/AdGuardHome/wiki/Clients#clientid';
export const MANUAL_UPDATE_LINK = 'https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ#manual-update';
export const PORT_53_FAQ_LINK = 'https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ#bindinuse';
export const PRIVACY_POLICY_LINK = 'https://link.adtidy.org/forward.html?action=privacy&from=ui&app=home';
export const UPSTREAM_CONFIGURATION_WIKI_LINK =
    'https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration#upstreams';

export const FILTERS_RELATIVE_LINK = '#filters';

export const ADDRESS_IN_USE_TEXT = 'address already in use';

export const INSTALL_FIRST_STEP = 1;
export const INSTALL_TOTAL_STEPS = 5;

export const SETTINGS_NAMES = {
    filtering: 'filtering',
    safebrowsing: 'safebrowsing',
    parental: 'parental',
    safesearch: 'safesearch',
};

export const STANDARD_DNS_PORT = 53;
export const STANDARD_WEB_PORT = 80;
export const STANDARD_HTTPS_PORT = 443;
export const DNS_OVER_TLS_PORT = 853;
export const DNS_OVER_QUIC_PORT = 853;
export const MIN_PORT = 1;
export const MAX_PORT = 65535;

export const EMPTY_DATE = '0001-01-01T00:00:00Z';

export const DEBOUNCE_TIMEOUT = 300;
export const DEBOUNCE_FILTER_TIMEOUT = 500;
export const CHECK_TIMEOUT = 1000;
export const HIDE_TOOLTIP_DELAY = 300;
export const SHOW_TOOLTIP_DELAY = 200;
export const MODAL_OPEN_TIMEOUT = 150;

export const UNSAFE_PORTS = [
    1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, 43, 53, 77, 79, 87, 95, 101, 102, 103, 104, 109, 110, 111,
    113, 115, 117, 119, 123, 135, 139, 143, 179, 389, 465, 512, 513, 514, 515, 526, 530, 531, 532, 540, 556, 563, 587,
    601, 636, 993, 995, 2049, 3659, 4045, 6000, 6665, 6666, 6667, 6668, 6669,
];

export const ALL_INTERFACES_IP = '0.0.0.0';

export const STATUS_RESPONSE = {
    YES: 'yes',
    NO: 'no',
    ERROR: 'error',
} as const;

export const MODAL_TYPE = {
    SELECT_MODAL_TYPE: 'SELECT_MODAL_TYPE',
    ADD_FILTERS: 'ADD_FILTERS',
    EDIT_FILTERS: 'EDIT_FILTERS',
    CHOOSE_FILTERING_LIST: 'CHOOSE_FILTERING_LIST',
    ADD_REWRITE: 'ADD_REWRITE',
    EDIT_REWRITE: 'EDIT_REWRITE',
    EDIT_LEASE: 'EDIT_LEASE',
    ADD_LEASE: 'ADD_LEASE',
    ADD_CLIENT: 'ADD_CLIENT',
    EDIT_CLIENT: 'EDIT_CLIENT',
};

export const CLIENT_ID = {
    MAC: 'mac',
    IP: 'ip',
};

export const MENU_URLS = {
    root: '/',
    logs: '/logs',
    guide: '/guide',
};

export const SETTINGS_URLS = {
    encryption: '/encryption',
    dhcp: '/dhcp',
    dns: '/dns',
    settings: '/settings',
    clients: '/clients',
};

export const FILTERS_URLS = {
    dns_blocklists: '/filters',
    dns_allowlists: '/dns_allowlists',
    dns_rewrites: '/dns_rewrites',
    custom_rules: '/custom_rules',
    blocked_services: '/blocked_services',
};

export const ENCRYPTION_SOURCE = {
    PATH: 'path',
    CONTENT: 'content',
};

export const FILTERED = 'Filtered';
export const NOT_FILTERED = 'NotFiltered';

export const DISABLED_STATS_INTERVAL = 0;

export const HOUR = 60 * 60 * 1000;

export const DAY_HOURS = 24;

export const DAY = HOUR * DAY_HOURS;

export const STATS_INTERVALS_DAYS = [DAY, DAY * 7, DAY * 30, DAY * 90];

export const QUERY_LOG_INTERVALS_DAYS = [HOUR * 6, DAY, DAY * 7, DAY * 30, DAY * 90];

export const RETENTION_CUSTOM = 1;

export const RETENTION_CUSTOM_INPUT = 'custom_retention_input';

export const CUSTOM_INTERVAL = 'customInterval';

export const FILTERS_INTERVALS_HOURS = [0, 1, 12, 24, 72, 168];

// Note that translation strings contain these modes (blocking_mode_CONSTANT)
// i.e. blocking_mode_default, blocking_mode_null_ip
export const BLOCKING_MODES = {
    default: 'default',
    refused: 'refused',
    nxdomain: 'nxdomain',
    null_ip: 'null_ip',
    custom_ip: 'custom_ip',
};

// Note that translation strings contain these modes (theme_CONSTANT)
// i.e. theme_auto, theme_light.
export const THEMES = {
    auto: 'auto',
    dark: 'dark',
    light: 'light',
};

export const WHOIS_ICONS = {
    location: 'location',
    orgname: 'network',
    netname: 'network',
    descr: '',
};

export const DEFAULT_LOGS_FILTER = {
    search: '',
    response_status: 'all',
};

export const DEFAULT_LANGUAGE = 'en';

export const QUERY_LOGS_PAGE_LIMIT = 20;

export const LEASES_TABLE_DEFAULT_PAGE_SIZE = 20;

export const FILTERED_STATUS = {
    FILTERED_BLACK_LIST: 'FilteredBlackList',
    NOT_FILTERED_WHITE_LIST: 'NotFilteredWhiteList',
    NOT_FILTERED_NOT_FOUND: 'NotFilteredNotFound',
    FILTERED_BLOCKED_SERVICE: 'FilteredBlockedService',
    REWRITE: 'Rewrite',
    REWRITE_HOSTS: 'RewriteEtcHosts',
    REWRITE_RULE: 'RewriteRule',
    FILTERED_SAFE_SEARCH: 'FilteredSafeSearch',
    FILTERED_SAFE_BROWSING: 'FilteredSafeBrowsing',
    FILTERED_PARENTAL: 'FilteredParental',
};

export const RESPONSE_FILTER = {
    ALL: {
        QUERY: 'all',
        LABEL: 'all_queries',
    },
    FILTERED: {
        QUERY: 'filtered',
        LABEL: 'filtered',
    },
    PROCESSED: {
        QUERY: 'processed',
        LABEL: 'show_processed_responses',
    },
    BLOCKED: {
        QUERY: 'blocked',
        LABEL: 'show_blocked_responses',
    },
    BLOCKED_SERVICES: {
        QUERY: 'blocked_services',
        LABEL: 'blocked_services',
    },
    BLOCKED_THREATS: {
        QUERY: 'blocked_safebrowsing',
        LABEL: 'blocked_threats',
    },
    BLOCKED_ADULT_WEBSITES: {
        QUERY: 'blocked_parental',
        LABEL: 'blocked_adult_websites',
    },
    ALLOWED: {
        QUERY: 'whitelisted',
        LABEL: 'allowed',
    },
    REWRITTEN: {
        QUERY: 'rewritten',
        LABEL: 'rewritten',
    },
    SAFE_SEARCH: {
        QUERY: 'safe_search',
        LABEL: 'safe_search',
    },
};

export const RESPONSE_FILTER_QUERIES = Object.values(RESPONSE_FILTER).reduce(
    (
        acc: Record<string, string>,
        {
            QUERY,
        }: {
            QUERY: string;
        },
    ) => {
        acc[QUERY] = QUERY;
        return acc;
    },
    {},
);

export const QUERY_STATUS_COLORS = {
    BLUE: 'blue',
    GREEN: 'green',
    RED: 'red',
    WHITE: 'white',
    YELLOW: 'yellow',
};

export const FILTERED_STATUS_TO_META_MAP = {
    [FILTERED_STATUS.NOT_FILTERED_WHITE_LIST]: {
        LABEL: RESPONSE_FILTER.ALLOWED.LABEL,
        COLOR: QUERY_STATUS_COLORS.GREEN,
    },
    [FILTERED_STATUS.NOT_FILTERED_NOT_FOUND]: {
        LABEL: RESPONSE_FILTER.PROCESSED.LABEL,
        COLOR: QUERY_STATUS_COLORS.WHITE,
    },
    [FILTERED_STATUS.FILTERED_BLOCKED_SERVICE]: {
        LABEL: 'blocked_service',
        COLOR: QUERY_STATUS_COLORS.RED,
    },
    [FILTERED_STATUS.FILTERED_SAFE_SEARCH]: {
        LABEL: RESPONSE_FILTER.SAFE_SEARCH.LABEL,
        COLOR: QUERY_STATUS_COLORS.YELLOW,
    },
    [FILTERED_STATUS.FILTERED_BLACK_LIST]: {
        LABEL: RESPONSE_FILTER.BLOCKED.LABEL,
        COLOR: QUERY_STATUS_COLORS.RED,
    },
    [FILTERED_STATUS.REWRITE]: {
        LABEL: RESPONSE_FILTER.REWRITTEN.LABEL,
        COLOR: QUERY_STATUS_COLORS.BLUE,
    },
    [FILTERED_STATUS.REWRITE_HOSTS]: {
        LABEL: RESPONSE_FILTER.REWRITTEN.LABEL,
        COLOR: QUERY_STATUS_COLORS.BLUE,
    },
    [FILTERED_STATUS.REWRITE_RULE]: {
        LABEL: RESPONSE_FILTER.REWRITTEN.LABEL,
        COLOR: QUERY_STATUS_COLORS.BLUE,
    },
    [FILTERED_STATUS.FILTERED_SAFE_BROWSING]: {
        LABEL: RESPONSE_FILTER.BLOCKED_THREATS.LABEL,
        COLOR: QUERY_STATUS_COLORS.YELLOW,
    },
    [FILTERED_STATUS.FILTERED_PARENTAL]: {
        LABEL: RESPONSE_FILTER.BLOCKED_ADULT_WEBSITES.LABEL,
        COLOR: QUERY_STATUS_COLORS.YELLOW,
    },
};

export const DEFAULT_TIME_FORMAT = 'HH:mm:ss';

export const LONG_TIME_FORMAT = 'HH:mm:ss.SSS';

export const DEFAULT_SHORT_DATE_FORMAT_OPTIONS = {
    year: 'numeric',
    month: 'numeric',
    day: 'numeric',
    hour12: false,
} as const;

export const DEFAULT_DATE_FORMAT_OPTIONS = {
    year: 'numeric',
    month: 'numeric',
    day: 'numeric',
    hour: 'numeric',
    hourCycle: 'h23',
    minute: 'numeric',
} as const;

export const DETAILED_DATE_FORMAT_OPTIONS = {
    ...DEFAULT_DATE_FORMAT_OPTIONS,
    month: 'long',
} as const;

export const SPECIAL_FILTER_ID = {
    CUSTOM_FILTERING_RULES: 0,
    SYSTEM_HOSTS: -1,
    BLOCKED_SERVICES: -2,
    PARENTAL: -3,
    SAFE_BROWSING: -4,
    SAFE_SEARCH: -5,
};

export const BLOCK_ACTIONS = {
    BLOCK: 'block',
    UNBLOCK: 'unblock',
};

export const SCHEME_TO_PROTOCOL_MAP = {
    dnscrypt: 'dnscrypt',
    doh: 'dns_over_https',
    dot: 'dns_over_tls',
    doq: 'dns_over_quic',
    '': 'plain_dns',
};

export const DNS_REQUEST_OPTIONS = {
    PARALLEL: 'parallel',
    FASTEST_ADDR: 'fastest_addr',
    LOAD_BALANCING: 'load_balance',
};

export const DHCP_FORM_NAMES = {
    DHCPv4: 'dhcpv4',
    DHCPv6: 'dhcpv6',
    DHCP_INTERFACES: 'dhcpInterfaces',
};

export const FORM_NAME = {
    UPSTREAM: 'upstream',
    DOMAIN_CHECK: 'domainCheck',
    FILTER: 'filter',
    REWRITES: 'rewrites',
    LOGS_FILTER: 'logsFilter',
    CLIENT: 'client',
    LEASE: 'lease',
    ACCESS: 'access',
    BLOCKING_MODE: 'blockingMode',
    ENCRYPTION: 'encryption',
    FILTER_CONFIG: 'filterConfig',
    LOG_CONFIG: 'logConfig',
    SERVICES: 'services',
    STATS_CONFIG: 'statsConfig',
    INSTALL: 'install',
    LOGIN: 'login',
    CACHE: 'cache',
    MOBILE_CONFIG: 'mobileConfig',
    ...DHCP_FORM_NAMES,
};

export const SMALL_SCREEN_SIZE = 767;
export const MEDIUM_SCREEN_SIZE = 1024;

export const SECONDS_IN_DAY = 60 * 60 * 24;

export const UINT32_RANGE = {
    MIN: 0,
    MAX: 4294967295,
};

export const RETENTION_RANGE = {
    MIN: 1,
    MAX: 365 * 24,
};

export const DHCP_VALUES_PLACEHOLDERS = {
    ipv4: {
        subnet_mask: '255.255.255.0',
        lease_duration: SECONDS_IN_DAY.toString(),
    },
    ipv6: {
        range_start: '2001::1',
        range_end: 'ff',
        lease_duration: SECONDS_IN_DAY.toString(),
    },
};

export const DHCP_DESCRIPTION_PLACEHOLDERS = {
    ipv4: {
        gateway_ip: 'dhcp_form_gateway_input',
        subnet_mask: 'dhcp_form_subnet_input',
        range_start: 'dhcp_form_range_start',
        range_end: 'dhcp_form_range_end',
        lease_duration: 'dhcp_form_lease_input',
    },
    ipv6: {
        range_start: 'dhcp_form_range_start',
        range_end: 'dhcp_form_range_end',
        lease_duration: 'dhcp_form_lease_input',
    },
};

export const TOAST_TRANSITION_TIMEOUT = 500;

export const TOAST_TYPES = {
    SUCCESS: 'success',
    ERROR: 'error',
    NOTICE: 'notice',
};

export const SUCCESS_TOAST_TIMEOUT = 5000;

export const ONE_SECOND_IN_MS = 1000;
export const FAILURE_TOAST_TIMEOUT = 30000;

export const TOAST_TIMEOUTS = {
    [TOAST_TYPES.SUCCESS]: SUCCESS_TOAST_TIMEOUT,
    [TOAST_TYPES.ERROR]: FAILURE_TOAST_TIMEOUT,
    [TOAST_TYPES.NOTICE]: FAILURE_TOAST_TIMEOUT,
};

export const ADDRESS_TYPES = {
    IP: 'IP',
    CIDR: 'CIDR',
    CLIENT_ID: 'CLIENT_ID',
    UNKNOWN: 'UNKNOWN',
};

export const CACHE_CONFIG_FIELDS = {
    cache_size: 'cache_size',
    cache_ttl_min: 'cache_ttl_min',
    cache_ttl_max: 'cache_ttl_max',
};

export const isFirefox = navigator.userAgent.indexOf('Firefox') !== -1;
export const COMMENT_LINE_DEFAULT_TOKEN = '#';

export const MOBILE_CONFIG_LINKS = {
    DOT: 'apple/dot.mobileconfig',
    DOH: 'apple/doh.mobileconfig',
};

// Timings for disable protection in milliseconds
export const DISABLE_PROTECTION_TIMINGS = {
    HALF_MINUTE: 30 * 1000,
    MINUTE: 60 * 1000,
    TEN_MINUTES: 10 * 60 * 1000,
    HOUR: 60 * 60 * 1000,
    TOMORROW: 24 * 60 * 60 * 1000,
};

export const LOCAL_TIMEZONE_VALUE = 'Local';

export const TABLES_MIN_ROWS = 5;

export const DASHBOARD_TABLES_DEFAULT_PAGE_SIZE = 100;

export const TIME_UNITS = {
    HOURS: 'hours',
    DAYS: 'days',
};

export const DNS_RECORD_TYPES = [
    "A", "AAAA", "AFSDB", "APL", "CAA", "CDNSKEY", "CDS", "CERT", "CNAME",
    "CSYNC", "DHCID", "DLV", "DNAME", "DNSKEY", "DS", "EUI48", "EUI64",
    "HINFO", "HIP", "HTTPS", "IPSECKEY", "KEY", "KX", "LOC", "MX", "NAPTR",
    "NS", "NSEC", "NSEC3", "NSEC3PARAM", "OPENPGPKEY", "PTR", "RP", "RRSIG",
    "SIG", "SMIMEA", "SOA", "SRV", "SSHFP", "SVCB", "TA", "TKEY",
    "TLSA", "TSIG", "TXT", "URI", "ZONEMD"
];
