pragma solidity >0.6.11;

// Author:	Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746
// SPDX-License-Identifier:	GPL-3.0-or-later
// File-version: 2
// Description: Top-level smart contract registry for the CIC network


contract CICRegistry {
	// Implements EIP 173
	address public owner;

	bytes32[] public identifiers;
	mapping (bytes32 => address) entries;		// contractidentifier -> address
	mapping (bytes32 => bytes32[]) entryBindings;	// contractidentifier -> chainidentifier

	constructor(bytes32[] memory _identifiers) public {
		owner = msg.sender;
		for (uint i = 0; i < _identifiers.length; i++) {
			identifiers.push(_identifiers[i]);
		}
	}

	function set(bytes32 _identifier, address _address) public returns (bool) {
		require(msg.sender == owner);
		require(entries[_identifier] == address(0));
		require(_address != address(0));

		bool found = false;
		for (uint i = 0; i < identifiers.length; i++) {
			if (identifiers[i] == _identifier) {
				found = true;
			}	
		}
		require(found);

		entries[_identifier] = _address;
		return true;
	}

	function bind(bytes32 _identifier, bytes32 _reference) public returns (bool) {
		require(msg.sender == owner);
		require(entries[_identifier] != address(0));

		entryBindings[_identifier].push(_reference);
	}

	// Implements EIP 173
	function transferOwnership(address _newOwner) public returns (bool) {
		require(msg.sender == owner);
		owner = _newOwner;
		return true;
	}

	// Implements Registry
	function addressOf(bytes32 _identifier) public view returns (address) {
		return entries[_identifier];
	}

	function supportsInterface(bytes4 _sum) public pure returns (bool) {
		if (_sum == 0xffeb6416) { // Registry
			return true;
		}
		if (_sum == 0xbb34534c) { // RegistryClient
			return true;
		}
		if (_sum == 0x01ffc9a7) { // EIP165
			return true;
		}
		if (_sum == 0x9493f8b2) { // EIP173
			return true;
		}
		return false;
	}
}