//pragma solidity >=0.6.10 <0.8.20;
pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;

import "../Table.sol";
//个人证书，存储各个个人的来自组织颁发的身份凭证，可预计范围内，用户数量大约在数十万级别，不用分表
contract PersonCert {
    event CreateResult(int256 count);
    event InsertResult(int256 count);
    event UpdateResult(int256 count);
    event RemoveResult(int256 count);
    

    struct PersonCertData{
        string weid;//用户的weid
        string issuer_name;//颁发者名称
        string issuer_public_key;//颁发者的公钥，16进制字符串
        string credential_content;//证书内容，以上所有字段均可由证书内容解析出来
        int256 create_time;
        int256 update_time;
        int256 invalid_time;//设置为无效的时间
        string status;//valid;invalid;
    }

    TableFactory tableFactory;
    string constant TABLE_NAME = "person_cert";
    string constant KEY_NAME = "key";
    string constant KEY_VALUE = "key";
    constructor() public {
        tableFactory = TableFactory(0x1001); //The fixed address is 0x1001 for TableFactory
        // the parameters of createTable are tableName,keyField,"vlaueFiled1,vlaueFiled2,vlaueFiled3,..."
        //创建表
        tableFactory.createTable(TABLE_NAME, KEY_NAME, "weid,issuer_name,issuer_public_key,credential_content,create_time,update_time,invalid_time,status");
    }
    
    
    
    function select()
    public
    view
    returns (PersonCertData[] memory){
        Table table = tableFactory.openTable(TABLE_NAME);

        Condition condition = table.newCondition();
        Entries entries = table.select(KEY_VALUE, condition);
        uint256  dataLen =   uint256(entries.size());
        PersonCertData[] memory pArray = new PersonCertData[](dataLen);

        for (uint256 i = 0; i < dataLen; ++i) {
            Entry entry = entries.get(int256(i));
            pArray[i]=PersonCertData(entry.getString("weid"),entry.getString("issuer_name"),entry.getString("issuer_public_key"),entry.getString("credential_content"),entry.getInt("create_time"),entry.getInt("update_time"),entry.getInt("invalid_time"),entry.getString("status"));

        }
        
        return pArray;
    }
    
    function selectByWeid(string memory weid)
    public
    view
    returns (PersonCertData[] memory){
        Table table = tableFactory.openTable(TABLE_NAME);

        Condition condition = table.newCondition();
        condition.EQ("weid", weid);
        Entries entries = table.select(KEY_VALUE, condition);
        uint256  dataLen =   uint256(entries.size());
        PersonCertData[] memory pArray = new PersonCertData[](dataLen);

        for (uint256 i = 0; i < dataLen; ++i) {
            Entry entry = entries.get(int256(i));
            pArray[i]=PersonCertData(entry.getString("weid"),entry.getString("issuer_name"),entry.getString("issuer_public_key"),entry.getString("credential_content"),entry.getInt("create_time"),entry.getInt("update_time"),entry.getInt("invalid_time"),entry.getString("status"));
        }
        
        return pArray;
    }
    
    function insert(string memory weid,string memory issuer_name,string issuer_public_key,string credential_content,int256 create_time,int256 update_time, int256 invalid_time,string status) 
    public 
    returns(int256,string memory){
        if(existByWeid(weid)){
            return (0,"weid can not repeat");
        }
        
        Table table = tableFactory.openTable(TABLE_NAME);
        Entry entry = table.newEntry();
        entry.set(KEY_NAME, KEY_VALUE);
        entry.set("weid", weid);
        entry.set("issuer_name", issuer_name);
        entry.set("issuer_public_key", issuer_public_key);
        entry.set("credential_content", credential_content);
        entry.set("create_time", create_time);
        entry.set("update_time", update_time);
        entry.set("invalid_time", invalid_time);
        entry.set("status", status);

        int256 count = table.insert(KEY_VALUE, entry);
        if(count>0){
            emit InsertResult(count);
        }
    
        return (count,"success");
    }
    
   
    
    
     //根据weid删除，实际上是更新状态为invalid
    function remove(string memory weid,int256 update_time) 
    public 
    returns (int256) {
        
        Table table = tableFactory.openTable(TABLE_NAME);
        
        Entry entry = table.newEntry();
        entry.set("update_time",update_time);
        entry.set("invalid_time",update_time);
        entry.set("status","invalid");

        Condition condition = table.newCondition();
        condition.EQ("weid", weid);

        int256 count = table.update(KEY_VALUE, entry, condition);
        if(count>0){
            emit UpdateResult(count);
        }
        
        return count;
    }
    
    
    
    //根据public_key判定是否存在
    function existByWeid(string memory weid)
    private
    view
    returns (bool){
        Table table = tableFactory.openTable(TABLE_NAME);
        Condition condition = table.newCondition();
        condition.EQ("weid", weid);
        Entries entries = table.select(KEY_VALUE, condition);
        return entries.size()>0;
    }

    
}