//! Accounts exported from Winauth are in the following format:
//!
//! One account per line, with each account represented as a URL.
//!
//! ```ignore
//! otpauth://totp/Steam:<steamaccountname>?secret=<ABCDEFG1234_secret_dunno_what_for>&digits=5&issuer=Steam&deviceid=<URL_Escaped_device_name>&data=<url_encoded_data_json>
//! ```
//!
//! The `data` field is a URL encoded JSON object with the following fields:
//!
//! ```json
//! {"steamid":"<steam_id>","status":1,"shared_secret":"<shared_secret>","serial_number":"<serial_number>","revocation_code":"<revocation_code>","uri":"<uri>","server_time":"<server_time>","account_name":"<steam_login_name>","token_gid":"<token_gid>","identity_secret":"<identity_secret>","secret_1":"<secret_1>","steamguard_scheme":"2"}
//! ```

use anyhow::Context;
use log::*;
use reqwest::Url;

use super::migrate::ExternalAccount;

pub(crate) fn parse_winauth_exports(buf: Vec<u8>) -> anyhow::Result<Vec<ExternalAccount>> {
	let buf = String::from_utf8(buf)?;
	let mut accounts = Vec::new();
	for line in buf.split('\n') {
		if line.is_empty() {
			continue;
		}
		let url = Url::parse(line).context("parsing as winauth export URL")?;
		let mut query = url.query_pairs();
		let issuer = query
			.find(|(key, _)| key == "issuer")
			.context("missing issuer field")?
			.1;
		if issuer != "Steam" {
			debug!("skipping non-Steam account: {}", issuer);
			continue;
		}
		let data = query
			.find(|(key, _)| key == "data")
			.context("missing data field")?
			.1;

		trace!("data: {}", data);

		let mut deser = serde_json::Deserializer::from_str(&data);
		let account = serde_path_to_error::deserialize(&mut deser)?;
		accounts.push(account);
	}
	Ok(accounts)
}