/*****************************************************************************
 *
 * Copyright (c) 2018-19, Eduard Gerlits, Paula Herber, Josef Treus
 * Westfälische Wilhelms-Universität Münster, AG Embedded Systems 
 * All rights reserved.
 *
 * This file is part of SysCSec
 *
 * SysCSec 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.
 *
 * SysCSec 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 SysCSec.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 *  Please report any problems or bugs to: sysc.sec@uni-muenster.de
 *
 ****************************************************************************/

#ifndef _ECCSYSTEM_H_
#define _ECCSYSTEM_H_

#include <systemc.h>
#include <stdlib.h>
#include <time.h>

#include "ecc_domain_parameters.h"
#include "Client.h"
#include "Server.h"
#include "CA.h"

SC_MODULE(SystemModule){

	// Module
	Client client;
	Server server;
	CertificateAuthority ca;
	
	// Fifo instantiation
	sc_fifo<sc_biguint<960> > fifo_client_ca;
	sc_fifo<sc_biguint<960> > fifo_ca_client;
	sc_fifo<sc_biguint<960> > fifo_server_ca;
	sc_fifo<sc_biguint<960> > fifo_ca_server;
	sc_fifo<sc_biguint<960> > fifo_client_server;
	sc_fifo<sc_biguint<960> > fifo_server_client;

	SC_HAS_PROCESS(SystemModule);
	SystemModule(sc_module_name instname, 
			bool useUAF,
			sc_biguint<160> ec_param_a_, 
			sc_biguint<160> ec_param_b_,
			sc_biguint<160> m_, 
			sc_biguint<160> g_x_, 
			sc_biguint<160> g_y_, 
			sc_biguint<160> n_ 
			) : 		client("client",useUAF, ec_param_a_, ec_param_b_, m_, g_x_, g_y_, n_), 
						server("server",useUAF, ec_param_a_, ec_param_b_, m_, g_x_, g_y_, n_),
						ca("ca", ec_param_a_, ec_param_b_, m_, g_x_, g_y_, n_)

	{


		std::cout << "[" << sc_time_stamp() << "]" << "[System]" << ": " << "Initializing system with the following curve parameters:" << std::endl;
		std::cout << "\t" << "Curve parameter a: " << ec_param_a_ << std::endl;
		std::cout << "\t" << "Curve parameter b: " << ec_param_b_ << std::endl;
		std::cout << "\t" << "Prime field m: " << m_ << std::endl;
		std::cout << "\t" << "Point G: (" << g_x_ << "," << g_y_ << ")" << std::endl;
		std::cout << "\t" << "Order of G: " << n_ << std::endl;



		srand(time(0));

		// connect fifos 

		/// CA
		ca.in_client(fifo_client_ca);
		ca.in_server(fifo_server_ca);
		ca.out_client(fifo_ca_client);
		ca.out_server(fifo_ca_server);

		/// Client
		client.in_ca(fifo_ca_client);
		client.in_server(fifo_server_client);
		client.out_ca(fifo_client_ca);
		client.out_server(fifo_client_server);

		/// Server
		server.in_ca(fifo_ca_server);
		server.in_client(fifo_client_server);
		server.out_ca(fifo_server_ca);
		server.out_client(fifo_server_client);

	}

};

#endif
