use crate::theme::*;

impl From<TomlTheme> for Theme {
    fn from(toml: TomlTheme) -> Self {
        Theme {
            keywords: toml.keywords.map_or_else(Vec::new, |keywords| {
                keywords.into_iter().map(KeywordConfig::from).collect()
            }),
            regexes: toml
                .regexes
                .map_or_else(Vec::new, |regexes| regexes.into_iter().map(RegexConfig::from).collect()),
            numbers: toml.numbers.map_or_else(NumberConfig::default, NumberConfig::from),
            uuids: toml.uuids.map_or_else(UuidConfig::default, UuidConfig::from),
            quotes: toml.quotes.map_or_else(QuoteConfig::default, QuoteConfig::from),
            ip_v4_addresses: toml.ip_addresses.map_or_else(IpV4Config::default, IpV4Config::from),
            ip_v6_addresses: toml.ip_addresses.map_or_else(IpV6Config::default, IpV6Config::from),
            dates: toml.dates.map_or_else(DateTimeConfig::default, DateTimeConfig::from),
            paths: toml.paths.map_or_else(UnixPathConfig::default, UnixPathConfig::from),
            urls: toml.urls.map_or_else(UrlConfig::default, UrlConfig::from),
            emails: toml.emails.map_or_else(EmailConfig::default, EmailConfig::from),
            pointers: toml.pointers.map_or_else(PointerConfig::default, PointerConfig::from),
            json: toml.json.map_or_else(JsonConfig::default, JsonConfig::from),
            jvm_stack_traces: toml
                .jvm_stack_traces
                .map_or_else(JvmStackTraceConfig::default, JvmStackTraceConfig::from),
            processes: toml
                .processes
                .map_or_else(UnixProcessConfig::default, UnixProcessConfig::from),
            key_value_pairs: toml
                .key_value_pairs
                .map_or_else(KeyValueConfig::default, KeyValueConfig::from),
        }
    }
}

impl From<KeywordToml> for KeywordConfig {
    fn from(keyword_toml: KeywordToml) -> Self {
        KeywordConfig {
            words: keyword_toml.words,
            style: keyword_toml.style,
        }
    }
}

impl From<RegexToml> for RegexConfig {
    fn from(regex_toml: RegexToml) -> Self {
        RegexConfig {
            regex: regex_toml.regex,
            style: regex_toml.style,
        }
    }
}

impl From<NumberToml> for NumberConfig {
    fn from(number_toml: NumberToml) -> Self {
        let default_config = NumberConfig::default();

        NumberConfig {
            style: number_toml.number.unwrap_or(default_config.style),
        }
    }
}

impl From<UuidToml> for UuidConfig {
    fn from(uuid_toml: UuidToml) -> Self {
        let default_config = UuidConfig::default();

        UuidConfig {
            number: uuid_toml.number.unwrap_or(default_config.number),
            letter: uuid_toml.letter.unwrap_or(default_config.letter),
            separator: uuid_toml.separator.unwrap_or(default_config.separator),
        }
    }
}

impl From<QuotesToml> for QuoteConfig {
    fn from(quotes_toml: QuotesToml) -> Self {
        let default_config = QuoteConfig::default();

        QuoteConfig {
            quote_token: quotes_toml
                .quote_token
                .filter(char::is_ascii)
                .map_or(default_config.quote_token, |ch| ch as u8),
            style: quotes_toml.style.unwrap_or(default_config.style),
        }
    }
}

impl From<IpToml> for IpV4Config {
    fn from(ip_toml: IpToml) -> Self {
        let default_config = IpV4Config::default();

        IpV4Config {
            number: ip_toml.number.unwrap_or(default_config.number),
            separator: ip_toml.separator.unwrap_or(default_config.separator),
        }
    }
}

impl From<IpToml> for IpV6Config {
    fn from(ip_toml: IpToml) -> Self {
        let default_config = IpV6Config::default();

        IpV6Config {
            number: ip_toml.number.unwrap_or(default_config.number),
            letter: ip_toml.letter.unwrap_or(default_config.letter),
            separator: ip_toml.separator.unwrap_or(default_config.separator),
        }
    }
}

impl From<DateToml> for DateTimeConfig {
    fn from(date_toml: DateToml) -> Self {
        let default_config = DateTimeConfig::default();

        DateTimeConfig {
            date: date_toml.date.unwrap_or(default_config.date),
            time: date_toml.time.unwrap_or(default_config.time),
            zone: date_toml.zone.unwrap_or(default_config.zone),
            separator: date_toml.separator.unwrap_or(default_config.separator),
        }
    }
}

impl From<PathToml> for UnixPathConfig {
    fn from(path_toml: PathToml) -> Self {
        let default_config = UnixPathConfig::default();

        UnixPathConfig {
            segment: path_toml.segment.unwrap_or(default_config.segment),
            separator: path_toml.separator.unwrap_or(default_config.separator),
        }
    }
}

impl From<UrlToml> for UrlConfig {
    fn from(url_toml: UrlToml) -> Self {
        let default_config = UrlConfig::default();

        UrlConfig {
            http: url_toml.http.unwrap_or(default_config.http),
            https: url_toml.https.unwrap_or(default_config.https),
            host: url_toml.host.unwrap_or(default_config.host),
            path: url_toml.path.unwrap_or(default_config.path),
            query_params_key: url_toml.query_params_key.unwrap_or(default_config.query_params_key),
            query_params_value: url_toml.query_params_value.unwrap_or(default_config.query_params_value),
            symbols: url_toml.symbols.unwrap_or(default_config.symbols),
        }
    }
}

impl From<EmailToml> for EmailConfig {
    fn from(email_toml: EmailToml) -> Self {
        let default_config = EmailConfig::default();

        EmailConfig {
            local_part: email_toml.local_part.unwrap_or(default_config.local_part),
            at_sign: email_toml.at_sign.unwrap_or(default_config.at_sign),
            domain: email_toml.domain.unwrap_or(default_config.domain),
            dot: email_toml.dot.unwrap_or(default_config.dot),
        }
    }
}

impl From<PointerToml> for PointerConfig {
    fn from(pointer_toml: PointerToml) -> Self {
        let default_config = PointerConfig::default();

        PointerConfig {
            number: pointer_toml.number.unwrap_or(default_config.number),
            letter: pointer_toml.letter.unwrap_or(default_config.letter),
            x: pointer_toml.x.unwrap_or(default_config.x),
        }
    }
}

impl From<KeyValueToml> for KeyValueConfig {
    fn from(key_value_toml: KeyValueToml) -> Self {
        let default_config = KeyValueConfig::default();

        KeyValueConfig {
            key: key_value_toml.key.unwrap_or(default_config.key),
            separator: key_value_toml.separator.unwrap_or(default_config.separator),
        }
    }
}

impl From<UnixProcessToml> for UnixProcessConfig {
    fn from(process_toml: UnixProcessToml) -> Self {
        let default_config = UnixProcessConfig::default();

        UnixProcessConfig {
            name: process_toml.name.unwrap_or(default_config.name),
            id: process_toml.id.unwrap_or(default_config.id),
            bracket: process_toml.bracket.unwrap_or(default_config.bracket),
        }
    }
}

impl From<JvmStackTraceToml> for JvmStackTraceConfig {
    fn from(toml: JvmStackTraceToml) -> Self {
        let default_config = JvmStackTraceConfig::default();

        JvmStackTraceConfig {
            caused_by: toml.caused_by.unwrap_or(default_config.caused_by),
            package: toml.package.unwrap_or(default_config.package),
            exception: toml.exception.unwrap_or(default_config.exception),
            frame: toml.frame.unwrap_or(default_config.frame),
            file: toml.file.unwrap_or(default_config.file),
            unknown_source: toml.unknown_source.unwrap_or(default_config.unknown_source),
            line_number: toml.line_number.unwrap_or(default_config.line_number),
        }
    }
}

impl From<JsonToml> for JsonConfig {
    fn from(json_toml: JsonToml) -> Self {
        let default_config = JsonConfig::default();

        JsonConfig {
            key: json_toml.key.unwrap_or(default_config.key),
            quote_token: json_toml.quote_token.unwrap_or(default_config.quote_token),
            curly_bracket: json_toml.curly_bracket.unwrap_or(default_config.curly_bracket),
            square_bracket: json_toml.square_bracket.unwrap_or(default_config.square_bracket),
            comma: json_toml.comma.unwrap_or(default_config.comma),
            colon: json_toml.colon.unwrap_or(default_config.colon),
        }
    }
}
