Documentation
use p256::ecdsa::{signature::Signer as p256Signer, Signature, SigningKey};
use prost::Message;

use cmpb::accesscontrol::Member;
use cmpb::common::Payload;
type MemberType = i32;

const MEMBER_TYPE_CERT: MemberType = 0;
const MEMBER_TYPE_PUBLIC_KEY: MemberType = 2;
const MEMBER_TYPE_DID: MemberType = 3;

type SignerError = String;
pub trait Signer {
    fn sign(&self, payload: &Payload) -> Result<Vec<u8>, SignerError>;
    fn new_member(&self) -> Member;
}

pub struct PublicModeSigner {
    publick_key: String,
    signer: SigningKey,
}

impl PublicModeSigner {
    pub fn from_sec_pem(s: &str) -> Result<Self, SignerError> {
        let secret_key = match p256::SecretKey::from_sec1_pem(s) {
            Err(e) => return Err(format!("failed to parse pem.")),
            Ok(s) => s,
        };

        let publick_key = secret_key.public_key().to_string();
        let signer = p256::ecdsa::SigningKey::from(secret_key);

        // signer.sign(msg)
        Ok(PublicModeSigner {
            publick_key,
            signer,
        })
    }
}

impl Signer for PublicModeSigner {
    // todo change error type
    fn sign(&self, payload: &Payload) -> Result<Vec<u8>, SignerError> {
        // todo try prost
        let data = payload.encode_to_vec();

        let s: Signature = self.signer.sign(data.as_ref());

        Ok(s.to_der().as_bytes().to_vec())
    }
    fn new_member(&self) -> Member {
        Member {
            org_id: "".to_string(),
            member_type: MEMBER_TYPE_PUBLIC_KEY,
            member_info: self.publick_key.clone().as_bytes().to_vec(),
        }
    }
}