use log::{error, warn};
use lyphedb::{KVList, KeyDirectory, LDBNatsMessage, LypheDBCommand, PropagationStrategy};
use crate::ldb::{construct_path, hash, DBConn};

pub const TITLESTORE: &str = "titlestore";

pub async fn add_url_to_titlewords(db: &DBConn, titlewords: &[&str], url: &str) -> Result<(), ()> {
    let mut key_sets = Vec::new();
    for titleword in titlewords {
        let path = construct_path(&[TITLESTORE, titleword, &hash(url)]).as_bytes().to_vec();
        key_sets.push((path, url.as_bytes().to_vec()));
    }
    let cmd = LDBNatsMessage::Command(LypheDBCommand::SetKeys(KVList {
        kvs: key_sets,
    }, PropagationStrategy::OnRead));

    match db.query(cmd).await {
        LDBNatsMessage::Success => {
            Ok(())
        }
        LDBNatsMessage::BadRequest => {
            error!("bad request for add_url_to_titlewords");
            Err(())
        }
        LDBNatsMessage::NotFound => {
            error!("not found for add_url_to_titlewords");
            Err(())
        }

        _ => {
            warn!("lyphedb sent weird message as response, treating as error");
            Err(())
        }
    }
}

pub async fn get_urls_from_titleword(db: &DBConn, titleword: &str) -> Result<Vec<String>, ()> {
    let path = construct_path(&[TITLESTORE, titleword]).as_bytes().to_vec();
    let cmd = LDBNatsMessage::Command(LypheDBCommand::GetKeyDirectory(KeyDirectory {
        key: path,
    }));
    
    match db.query(cmd).await {
        LDBNatsMessage::Entries(kvs) => {
            Ok(kvs.kvs.into_iter().map(|v| String::from_utf8_lossy(&v.1).to_string()).collect())
        }
        LDBNatsMessage::Success => {
            warn!("lyphedb responded with \"success\" to get_urls_from_titlewords, treating as error");
            Err(())
        }
        LDBNatsMessage::BadRequest => {
            warn!("bad request for get_urls_from_titlewords");
            Err(())
        }
        LDBNatsMessage::NotFound => {
            Ok(vec![])
        }
        _ => {
            warn!("lyphedb sent weird message as response, treating as error");
            Err(())
        }
    }
}