// Rshare - a file sharing program written in Rust.
// Copyright (C) 2017 Cooper Paul EdenDay
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Electronic mail: cedenday@protonmail.com
// Paper mail: 100 Front Street, #31, Bath, Maine, 04530, USA

use std;
use bincode;
use metadata::Part;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Message {
    Ping,
    Pong,
    IWantKey { key: Vec<u8> },
    DoYouHaveKey {
        key: Vec<u8>,
        contact_address: std::net::IpAddr,
    },
    DoYouWantHash { hash: Vec<u8>, public_key: Vec<u8> },
    IWantHash { hash: Vec<u8>, public_key: Vec<u8> },
    HereYouGo {
        public_key: Vec<u8>,
        decryption_salt: Vec<u8>,
        nonce: [u8; 12],
        hash: Vec<u8>,
        part: Part,
        ciphertext: Vec<u8>,
    },
}

pub fn encode(message: &Message) -> Vec<u8> {
    bincode::serialize(message, bincode::Infinite).expect("Couldn't encode data.")
}

pub fn decode(input: &[u8]) -> Result<Message, String> {
    let message: Result<Message, Box<bincode::ErrorKind>> = bincode::deserialize(input);
    if let Ok(message) = message {
        Ok(message)
    } else {
        Err(String::from("Couldn't parse Bincode."))
    }
}

#[test]
fn coding() {
    let my_message = Message::Ping;
    let encoded = encode(&my_message);
    let peer_message = decode(&encoded).unwrap();
    assert_eq!(my_message, peer_message);
}
