contract OneInchUsdEthChainlinkOracleId is OneInchUsdEthOracleSubId, IOracleId {
  event Provided(uint256 indexed timestamp, uint256 result);

  // Opium
  IOracleAggregator public oracleAggregator;

  // Governance
  address public _owner;
  uint256 public EMERGENCY_PERIOD;

  modifier onlyOwner() {
    require(_owner == msg.sender, "N.O"); // N.O = not an owner
    _;
  }

  constructor(IOracleAggregator _oracleAggregator, uint256 _emergencyPeriod) public {
    // Opium
    oracleAggregator = _oracleAggregator;

    // Governance
    _owner = msg.sender;
    EMERGENCY_PERIOD = _emergencyPeriod;
    /*
    {
      "author": "Opium.Team",
      "description": "1INCH/USD Oracle ID",
      "asset": "1INCH/USD",
      "type": "onchain",
      "source": "chainlink",
      "logic": "none",
      "path": "latestAnswer()"
    }
    */
    emit MetadataSet("{\"author\":\"Opium.Team\",\"description\":\"1INCH/USD Oracle ID\",\"asset\":\"1INCH/USD\",\"type\":\"onchain\",\"source\":\"chainlink\",\"logic\":\"none\",\"path\":\"latestAnswer()\"}");
  }

  /** OPIUM INTERFACE */
  function fetchData(uint256 _timestamp) external payable override {
    _timestamp;
    revert("N.S"); // N.S = not supported
  }

  function recursivelyFetchData(uint256 _timestamp, uint256 _period, uint256 _times) external payable override {
    _timestamp;
    _period;
    _times;
    revert("N.S"); // N.S = not supported
  }

  function calculateFetchPrice() external override returns (uint256) {
    return 0;
  }
  
  /** RESOLVER */
  function _callback(uint256 _timestamp) public {
    require(
      !oracleAggregator.hasData(address(this), _timestamp) &&
      _timestamp < now,
      "N.A" // N.A = Only when no data and after timestamp allowed
    );

    uint256 result = getResult();
    oracleAggregator.__callback(_timestamp, result);

    emit Provided(_timestamp, result);
  }

  /** GOVERNANCE */
  /** 
    Emergency callback allows to push data manually in case EMERGENCY_PERIOD elapsed and no data were provided
   */
  function emergencyCallback(uint256 _timestamp, uint256 _result) public onlyOwner {
    require(
      !oracleAggregator.hasData(address(this), _timestamp) &&
      _timestamp + EMERGENCY_PERIOD  < now,
      "N.E" // N.E = Only when no data and after emergency period allowed
    );

    oracleAggregator.__callback(_timestamp, _result);

    emit Provided(_timestamp, _result);
  }

  function changeOwner(address _newOwner) public onlyOwner {
    require(_newOwner != address(0));
    _owner = _newOwner;
  }

  function changeEmergencyPeriod(uint256 _newEmergencyPeriod) public onlyOwner {
    EMERGENCY_PERIOD = _newEmergencyPeriod;
  }
}
function fetchData(uint256 _timestamp) external payable override {
  _timestamp;
  revert("N.S"); // N.S = not supported
}

/** OPIUM INTERFACE */