
'use strict';
const express = require('express')
const fileUpload=require('express-fileupload');
const app = express()
app.set('view engine', 'ejs')
app.engine('html', require('ejs').renderFile);
const bodyParser = require('body-parser');
const url = require('url');
const querystring = require('querystring');
// Bring key classes into scope, most importantly Fabric SDK network class
const fs = require('fs');
const yaml = require('js-yaml');
const ipfsClient = require('ipfs-http-client')
//import { create } from 'ipfs-http-client';
app.use(express.static('public'))





const { Wallets } = require('fabric-network');
const path = require('path');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(fileUpload());
var cache = require('memory-cache');
const ProjectService = require('./services/ProjectService.js');
const QueryService = require( "./services/queryService.js" );
const QueryHistoryService = require( "./services/queryHistoryService.js" );
const WalletService = require( "./services/walletsService.js" );
const ClientService = require( "./services/ClientService.js" );
const EmployeeService = require( "./services/EmployeeService.js" );
const ProjectSvcInstance = new ProjectService();
const querySvcInstance = new QueryService();
const queryHistorySvcInstance = new QueryHistoryService();
const walletSvcInstance = new WalletService();
const clientInstance = new ClientService();
const employeeInstance = new EmployeeService();
const ipfs = ipfsClient.create({host:'172.29.3.95' , port:'5001', protocol:'http'});
//const client = ipfsClient('http://172.29.3.95:8080')


console.log("start app file   ");
app.use(function (req, res, next) {
  res.setHeader('Access-Control-Allow-', '*');
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.setHeader('Access-Control-Allow-Headers', '*');
  res.setHeader('Access-Control-Allow-Credentials', true);
  next();
  });



app.get('/', function (req, res) {

   res.render('index');
})

app.get('/projects', function (req, res) {

  res.render('projects.html');
})

app.get('/clients', function (req, res) {

  res.render('clients.html');
})

app.get('/addProject', function (req, res) {

  res.render('project-add.html');
})
app.get('/employees', function (req, res) {

  res.render('employee.html');
})

app.get('/projectDetail', function (req, res) {

  res.render('project-detail.html');
})






app.post('/addUser', async (req, res, next) => {

  var userName = req.body.userName;
  
  try {
    if(!userName || userName.lenth<1) {
      return res.status(500).json("          fff    User is missing");
    } else {
      const result = await walletSvcInstance.addToWallet(userName);
      //console.log("in app file :   "+result);
      //console.log("in app file :   "+userName);
      cache.put('userName', userName);
     // console.log("after cach");
      let msg = 'User '+ userName + ' was successfully registered and enrolled and is ready to intreact with the fabric network';
     // console.log(msg);
     // console.log(res.status(200).json(msg));
      return res.status(200).json(msg);

 
    }
  } catch (error) {
    console.log("Error from app file");

    return res.status(500).json(error);

  }
})


app.post('/addClient', async (req, res, next) => {
  //console.log("in app");
  //console.log(req.body);
  var firstName = req.body.firstName;
  var lastName = req.body.lastName;
  var phoneNumber=req.body.phoneNumber
  var email = req.body.email;
  var userName = cache.get('userName')
  try {
    if(!userName || userName.lenth<1) {
      console.log("User is missing");
      return res.status(500).json("User is missing");
    } else if (!firstName || !lastName || !phoneNumber || !email ) {
    console.log("Missing requied fields");
      return res.status(500).json("Missing requied fields");
    } else {
      console.log("befor acsess to block");
      const result =  await clientInstance.addNewClient(userName, firstName,lastName, phoneNumber,email);
      console.log("after acsess to block");
      return res.status(200).json(result);
    }
  } catch (error) {
    console.log("catch");
    return res.status(500).json(error);
  }
})


app.post('/addEmployee', async (req, res, next) => {
 // console.log("in app");
 // console.log(req.body);
  var firstName = req.body.firstName;
  var lastName = req.body.lastName;
  var phoneNumber=req.body.phoneNumber
  var email = req.body.email;
  var userName = cache.get('userName')
  try {
    if(!userName || userName.lenth<1) {
      console.log("User is missing");
      return res.status(500).json("User is missing");
    } else if (!firstName || !lastName || !phoneNumber || !email ) {
    console.log("Missing requied fields");
      return res.status(500).json("Missing requied fields");
    } else {
      console.log("befor acsess to block");
      const result =  await employeeInstance.addNewEmployee(userName, firstName,lastName, phoneNumber,email);
      console.log("after acsess to block");
      return res.status(200).json(result);
    }
  } catch (error) {
    console.log("catch");
    return res.status(500).json(error);
  }
})


///////////////////////////////////////////////////////////////////////////////////////////
app.get('/queryClient', async (req, res, next) => {
//  console.log("app:    queryClient ");
  var userName = cache.get('userName')
  let key = req.query.key;

 // console.log(userName);
  try {
    if(!userName || userName.lenth<1) {
    //  console.log("if in app");
      return res.status(500).json("User is missing");
    } else {
     // console.log("else in app");
      const result = await clientInstance.queryClient(userName , key);

      return res.status(200).json(result);
    } 
  } catch (error) {
    console.log("Erorr in app");

    return res.status(500).json(error);
  }

})


app.get('/queryAllClient', async (req, res, next) => {
  //console.log("app:     ");
  var userName = cache.get('userName')
 
  //console.log(userName);
  try {
    if(!userName || userName.lenth<1) {
    //  console.log("if in app");
      return res.status(500).json("User is missing");
    } else {
     // console.log("else in app");
      const result = await clientInstance.queryAllClient(userName);

      return res.status(200).json(result);
    } 
  } catch (error) {
    console.log("Erorr in app");

    return res.status(500).json(error);
  }

})



app.get('/queryEmployee', async (req, res, next) => {
 // console.log("app:     ");
  var userName = cache.get('userName')
  let key = req.query.key;

  //console.log(userName);
  try {
    if(!userName || userName.lenth<1) {
   //   console.log("if in app");
      return res.status(500).json("User is missing");
    } else {
     // console.log("else in app");
      const result = await employeeInstance.queryEmployee(userName , key);

      return res.status(200).json(result);
    } 
  } catch (error) {
    console.log("Erorr in app");

    return res.status(500).json(error);
  }

})

app.get('/queryAllEmployee', async (req, res, next) => {
  //console.log("app:     ");
  var userName = cache.get('userName')
 
  //console.log(userName);
  try {
    if(!userName || userName.lenth<1) {
     // console.log("if in app");
      return res.status(500).json("User is missing");
    } else {
     // console.log("else in app");
      const result = await employeeInstance.queryAllEmployee(userName);

      return res.status(200).json(result);
    } 
  } catch (error) {
    console.log("Erorr in app");

    return res.status(500).json(error);
  }

})
/////////////////////////////////////////////////////////////////////////////////////////
app.post('/addNewProject', async (req, res, next) => {
  //console.log("in app");

  //console.log(req.body);
  var projectName = req.body.projectName;
  var descreption = req.body.descreption;
  var projectStatus=req.body.projectStatus
  var clientID = req.body.clientID;
  var projectLeaderID=req.body.projectLeaderID;
  var estimatedBudget=req.body.estimatedBudget;
  var estimatedDuration=req.body.estimatedDuration;
  var deadline = req.body.deadline;
  

  //console.log(projectID);
 // var projectProgress=0;
 // console.log("in app");
  var userName = cache.get('userName')
  //console.log("in app");
  try {
    if(!userName || userName.lenth<1) {
      console.log("User is missing");
      return res.status(500).json("User is missing");
    } else if (!projectName || !clientID || !descreption || !deadline ||!projectStatus||!projectLeaderID||!estimatedDuration||!estimatedBudget) {console.log("EEEEEEEEEEEEEEEEEEEE");
    // console.log(projectName+clientID+descreption+deadline);
    // console.log(projectStatus+projectLeaderID+estimatedDuration+estimatedBudget);

      return res.status(500).json("Missing requied fields");
    } else {
      //console.log("befor acsess to block");

      const result =  await ProjectSvcInstance.addNewProject(userName,projectName, clientID, descreption ,deadline,projectStatus,projectLeaderID,estimatedDuration,estimatedBudget);
      //console.log("after acsess to block");

      return res.status(200).json(result);

    }
  } catch (error) {
    //console.log("catch");

    return res.status(500).json(error);
  }
})

app.get('/queryAllProjects', async (req, res, next) => {
  //console.log("app:     "+req.body);
  var userName = cache.get('userName')
  let key = req.query.key;
 // console.log(userName);
  try {
    if(!userName || userName.lenth<1) {
   //   console.log("if in app");
      return res.status(500).json("User is missing");
    } else {
     // console.log("else in app");
      const result = await querySvcInstance.queryAllProjects(userName ,key);

      return res.status(200).json(result);
    } 
  } catch (error) {
    console.log("Erorr in app");

    return res.status(500).json(error);
  }

})

app.get('/queryProject', async (req, res, next) => {
  
  var userName = cache.get('userName')
  let key = req.query.key;
  try {
    if(!userName || userName.lenth<1) {
      //console.log("if in app");
      return res.status(500).json("User is missing");
    } else {
      //console.log("else in app");
     // console.log("1");
      const result = await querySvcInstance.queryProject(userName,key);
     // console.log(result);
     //console.log("2");
      //console.log(result)
      return res.status(200).json(result);
    } 
  } catch (error) {
    console.log("Erorr in app");
  //  console.log("3");
    return res.status(500).json(error);
  }

})



app.get('/queryAllTasksForAProject', async (req, res, next) => {
  
  var userName = cache.get('userName')
  let key = req.query.key;
  try {
    if(!userName || userName.lenth<1) {
     // console.log("if in app");
      return res.status(500).json("User is missing");
    } else {
     // console.log("else in app");
     
      const result = await querySvcInstance.queryAllTasksForAProject(userName,key);
      console.log("result of queryAllTasksForAProject")
      console.log(result);


      return res.status(200).json(result);
    } 
  } catch (error) {
   // console.log("Erorr in app");

    return res.status(500).json(error);
  }

})

/////////////////////////////////////////////////////////////////////////////////////////
app.post('/addNewTask', async (req, res, next) => {
  console.log("in app");

  console.log(req.body);
  var projectID = req.body.projectID;
  var taskName = req.body.taskName;
  var taskdescreption = req.body.taskdescreption;
  var taskStatus=req.body.taskStatus;
  var defecaltDegree=req.body.defecaltDegree;
  var taskEmployeeID = req.body.taskEmployeeID;
  var estematedTaskDuration=req.body.estematedTaskDuration;
  var taskDeadline=req.body.taskDeadline;
  var taskWage = req.body.taskWage;

 
 
 // console.log("in app");
  var userName = cache.get('userName')
  //console.log("in app");
  try {
    if(!userName || userName.lenth<1) {
      console.log("User is missing");
      return res.status(500).json("User is missing");
    } else if (!projectID || !taskName || !taskdescreption || !taskStatus ||!defecaltDegree||!taskEmployeeID||!estematedTaskDuration||!taskDeadline||!taskWage) {console.log("EEEEEEEEEEEEEEEEEEEE");
    console.log("Missing requied fields");
      return res.status(500).json("Missing requied fields");
    } else {
     // console.log("befor acsess to block");

      const result =  await ProjectSvcInstance.addNewTask(userName, projectID, taskName, taskdescreption,taskStatus, defecaltDegree,taskEmployeeID,estematedTaskDuration,taskDeadline,taskWage);
    //  console.log("after acsess to block");

      return res.status(200).json(result);

    }
  } catch (error) {
    console.log("catch");

    return res.status(500).json(error);
  }
})




app.get('/queryHistoryByKey', async (req, res, next) => {
  console.log(req.body);
  var userName = cache.get('userName')
  //var userName = "brian";
  let key = req.query.key;
  try {
    if(!userName || userName.lenth<1) {
      return res.status(500).json("User is missing");
    } else {
      const result = await queryHistorySvcInstance.queryHistoryByKey(userName, key);
      return res.status(200).json(result);
    }
  } catch (error) {
    return res.status(500).json(error);
  }

})


app.get('/queryByKey', async (req, res, next) => {
  console.log(req.body);
  var userName = cache.get('userName')
  //var userName = "brian";
  let key = req.query.key;
  try {
    if(!userName || userName.lenth<1) {
      return res.status(500).json("User is missing");
    } else {
      const result = await querySvcInstance.queryByKey(userName, key);
      return res.status(200).json(result);
    }
  } catch (error) {
    return res.status(500).json(error);
  }

})





app.post('/uploadFile', async (req, res, next) => {
  //  console.log("app:    queryClient ");
    

   
   console.log("1");
    try {
     // if(!userName || userName.lenth<1) 
      //{
       // console.log("if in app");
       // return res.status(500).json("User is missing");
      //} else {


      const file=req.files.file;
      const fileName=req.body.fileName;
      const filePath='files/' +fileName;
//console.log(fileName);
file.mv(filePath ,async (err)=>{
if(err)
{
  console.log('Error:failed to download th file')
  return res.status(500).send(err);
}
const fileHash =await uploadFile(fileName, filePath);

console.log(fileHash)
res.render('',{fileHash})

})
        console.log("else in app");
      //  const hash= await uploadFile(req.query);
       // console.log(hash);
     
     // } 
    } catch (error) {
      console.log("Erorr in app");
      return res.status(500).json(error);
    }
  
  })
  const uploadFile =async (fileName , filePath)=>{
    console.log("submit file to ipfs")
    const file=fs.readFileSync(filePath);
    //console.log(filePath)
    //console.log(file)
    var fileHash;
    const  fileadded=await ipfs.add({path: fileName ,content:file}).then(res => fileHash=res.cid);;
    //console.log(fileadded)
    
    //const fileadded = await client.add(file)
    //const fileHash=fileadded.cid;

    fs.unlink(filePath,(err)=>{
      if(err) console.log("cannot delet"+err)
      });
    console.log(fileHash)
    if(fileHash.lenth<1||!fileHash)
    console.log("could not upload the file to ipfs")
    else
    return "http://172.29.3.95:8080/ipfs/"+fileHash+"";
  }













var port = process.env.PORT || 30000;
var server = app.listen(port, function () {
   var host = server.address().address
   var port = server.address().port
   console.log("App listening at http://%s:%s", host, port)
})
