package org.ourfilesystem.postcodec;

/*
OurFileSystem is a peer2peer file sharing program.
Copyright (C) 2012  Robert Gass

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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

*/

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

import org.ourfilesystem.db.LocalPost;
import org.ourfilesystem.utilities.BBytes;
import org.ourfilesystem.utilities.FileUtils;

public class Codec {

	private static long MagicCookie = 0x1adeadbeefc0de1L;
	
	public static PostDecoded decode(LocalPost post) {
		try {
			File mf = (File)post.getPost().getMessage();
			if (mf != null) {
				FileInputStream fis = new FileInputStream(mf);
				long cookie = FileUtils.readLong(fis);
				if (cookie == MagicCookie) {
					PostDecoded p = new PostDecoded();
					int numstrvals = FileUtils.readInt(fis);
					for (int c = 0; c < numstrvals; c++) {
						String k = FileUtils.readString(fis);
						int ksn = FileUtils.readInt(fis);
						for (int ki = 0; ki < ksn; ki++) {
							String v = FileUtils.readString(fis);
							p.pushStringValue(k, v);
						}
					}
					int numlongvals = FileUtils.readInt(fis);
					for (int c = 0; c < numlongvals; c++) {
						String k = FileUtils.readString(fis);
						long v = FileUtils.readLong(fis);
						p.getNumberValues().put(k, v);
					}
					int numrefvals = FileUtils.readInt(fis);
					for (int c = 0; c < numrefvals; c++) {
						String k = FileUtils.readString(fis);
						int n = FileUtils.readInt(fis);
						for (int rc = 0; rc < n; rc++) {
							BBytes bv = new BBytes(FileUtils.readBytes(fis));
							p.pushReferenceValue(k, bv);
						}
					}
					p.setComment(FileUtils.readString(fis));
					p.setPost(post);
					return p;
				}
				fis.close();
			}
		}
		catch (Exception e) {
		}
		return null;
	}
	
	public static void ecnode(PostDecoded p) throws IOException {
		File pf = (File)p.getPost().getPost().getMessage();
		FileOutputStream fos = new FileOutputStream(pf);
		FileUtils.writeLong(MagicCookie, fos);
		FileUtils.writeInt(p.getStringValues().size(), fos);
		Iterator<Entry<String,Set<String>>> is = p.getStringValues().entrySet().iterator();
		while (is.hasNext()) {
			Entry<String,Set<String>> e = is.next();
			FileUtils.writeString(e.getKey(), fos);
			Set<String> ss = e.getValue();
			FileUtils.writeInt(ss.size(), fos);
			Iterator<String> i2 = ss.iterator();
			while (i2.hasNext()) {
				FileUtils.writeString(i2.next(), fos);
			}
		}
		FileUtils.writeInt(p.getNumberValues().size(), fos);
		Iterator<Entry<String,Long>> il = p.getNumberValues().entrySet().iterator();
		while (il.hasNext()) {
			Entry<String,Long> e = il.next();
			FileUtils.writeString(e.getKey(), fos);
			FileUtils.writeLong(e.getValue(), fos);
		}
		FileUtils.writeInt(p.getOtherReferences().size(), fos);
		Iterator<Entry<String,Set<Object>>> io = p.getOtherReferences().entrySet().iterator();
		while (io.hasNext()) {
			Entry<String,Set<Object>> e = io.next();
			FileUtils.writeString(e.getKey(), fos);
			Set<Object> rs = e.getValue();
			FileUtils.writeInt(rs.size(), fos);
			Iterator<Object> ri = rs.iterator();
			while (ri.hasNext()) {
				BBytes bb = (BBytes)ri.next();
				FileUtils.writeBytes(fos, bb.getBytes());
			}
		}
		FileUtils.writeString(p.getComment(), fos);
		fos.close();
	}



}
