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

import "../Table.sol";
//组织证书，存储各个组织的来自CA颁发的数字证书
contract OrgCert {
    event CreateResult(int256 count);
    event InsertResult(int256 count);
    event UpdateResult(int256 count);
    event RemoveResult(int256 count);
    

    struct OrgCertData{
        string  public_key;//公钥，十六进制串
        string  issuer_name;//颁发者名称
        string  subject_name;//拥有者名称
        string  sig_alg_name;//签名算法名称
        string  cert_content;//证书内容，以上所有字段均可由证书内容解析出来
        int256 create_time;
        int256 update_time;
        string status;//valid;invalid;
    }

    TableFactory tableFactory;
    string constant TABLE_NAME = "org_cert2";
    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, "public_key,issuer_name,subject_name,sig_alg_name,cert_content,create_time,update_time,status");
    }
    
    
    
    function select()
    public
    view
    returns (OrgCertData[] memory){
        Table table = tableFactory.openTable(TABLE_NAME);

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

        for (uint256 i = 0; i < dataLen; ++i) {
            Entry entry = entries.get(int256(i));
            pArray[i]=OrgCertData(entry.getString("public_key"),entry.getString("issuer_name"),entry.getString("subject_name"),entry.getString("sig_alg_name"),entry.getString("cert_content"),entry.getInt("create_time"),entry.getInt("update_time"),entry.getString("status"));

        }
        
        return pArray;
    }
    
    function insert(string memory public_key,string memory issuer_name,string subject_name,string sig_alg_name,string cert_content,int256 create_time,int256 update_time, string status) 
    public 
    returns(int256,string memory){
        if(existByPublicKey(public_key)){
            return (0,"public_key can not repeat");
        }
        
        Table table = tableFactory.openTable(TABLE_NAME);
        Entry entry = table.newEntry();
        entry.set(KEY_NAME, KEY_VALUE);
        entry.set("public_key", public_key);
        entry.set("issuer_name", issuer_name);
        entry.set("subject_name", subject_name);
        entry.set("sig_alg_name", sig_alg_name);
        entry.set("cert_content", cert_content);
        entry.set("create_time", create_time);
        entry.set("update_time", update_time);
        entry.set("status", status);

        int256 count = table.insert(KEY_VALUE, entry);
        if(count>0){
            emit InsertResult(count);
        }
    

        return (count,"success");
    }
    
   
    
    
     //根据公钥删除，实际上是更新状态为invalid
    function remove(string memory public_key,int256 update_time) 
    public 
    returns (int256) {
        
        Table table = tableFactory.openTable(TABLE_NAME);
        
        Entry entry = table.newEntry();
        entry.set("update_time",update_time);
        entry.set("status","invalid");

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

        int256 count = table.update(KEY_VALUE, entry, condition);
        

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

    
}