use asn1_rs::{BitString, Class, Error, Explicit, Integer, OctetString, Oid, ParseResult, Sequence, TaggedValue};
use asn1_rs::FromDer;
use base64::Engine;
use base64::engine::GeneralPurpose;

const BASE64: GeneralPurpose = base64::engine::general_purpose::STANDARD;

fn main() {
    let private_key = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgakRmuDPA8pr1kqmY\
    PxjoMJSJzMeWllw0qbKWzrbEfzehRANCAAQs2XCluo7NF7Y0tL6Pp2GWz2fw5llF\
    dRvIpq0j8kVQjNOIYZqlBG6OOMQql3U95HsJJY0YzkoXEcdcJmoIV0zn";

    let private_key_der = BASE64.decode(private_key).unwrap();

    let r: ParseResult<()> = Sequence::from_der_and_then(&private_key_der, |i| {
        let (i, i0) = Integer::from_der(i)?;
        println!("INTEGER0: {}", i0.as_i8().unwrap());
        let r: ParseResult<()> = Sequence::from_der_and_then(i, |i| {
            let (i, oid1) = Oid::from_der(i)?;
            let (i, oid2) = Oid::from_der(i)?;

            println!("OID1: {}", oid1);
            println!("OID2: {}", oid2);
            Ok((i, ()))
        });

        let (i, _) = r.unwrap();

        let (i, octet) = OctetString::from_der(i).unwrap();
        let octet = octet.as_ref();

        let r: ParseResult<()> = Sequence::from_der_and_then(octet, |i| {
            let (i, i1) = Integer::from_der(i).unwrap();
            println!("INTEGER1: {}", i1.as_i8().unwrap());
            let (i, oct) = OctetString::from_der(i)?;
            println!("PRIVATE KEY: {}", hex::encode(oct.as_ref()));

            type TaggedValueContextSpecific<'a> = TaggedValue<BitString<'a>, Error, Explicit, { Class::CONTEXT_SPECIFIC }, 1>;
            let tagged_value = TaggedValueContextSpecific::from_der(i);
            let _ = tagged_value.map(|(_i, tagged_value)| {
                println!("Tagged value [{}]", tagged_value.tag().0);
                let tagged_value_inner = tagged_value.into_inner();
                println!("Tagged value: {}, unused: {}", hex::encode(tagged_value_inner.as_ref()), tagged_value_inner.unused_bits);
            });

            Ok((i, ()))
        });
        r.unwrap();
        Ok((i, ()))
    });
    r.unwrap();
}