// File: src/EtherGardenManager.sol



// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "solmate/auth/Owned.sol";
import "./ENS.sol";

contract EtherGardenManager is Owned {

    bytes32 constant public BASE_HASH = 0x00b35a7c08a6e1d845888ef50cfa5867ee7a3b9562f1843596d37437f31774fa;

    function computeNamehash(string memory _name) public pure returns (bytes32 namehash) {
        // shortcut to get to namehash for 'ether.garden'
        namehash = BASE_HASH;
        namehash = keccak256(
            abi.encodePacked(namehash, keccak256(abi.encodePacked(_name)))
        );
    }

    constructor() Owned(msg.sender) {
    }

    ENS private _ens = ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
    Resolver private _resolver = Resolver(_ens.resolver(BASE_HASH));

    bool private _isOpen = false;

    function setOpen(bool isOpen) external onlyOwner {
        _isOpen = isOpen;
    }

    //@dev assume the subdomain is correctly normalized etc pls don't break my contract (:
    function mintNewSubDomain(string memory newSub) external requireOpen {
        address newOwner = msg.sender;
        bytes32 subNodeLabel = keccak256(abi.encodePacked(newSub));
        bytes32 subNodeFull = computeNamehash(newSub);
        _ens.setSubnodeRecord(BASE_HASH, subNodeLabel, address(this), address(_resolver), 0);
        _resolver.setAddr(subNodeFull, newOwner);
        _ens.setOwner(subNodeFull, newOwner);
    }

    ///@dev modifier to only allow new registrations
    modifier requireOpen virtual {
        require(_isOpen, "Not open for registrations.");
        _;
    }

}

// File: lib/solmate/src/auth/Owned.sol



// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

// File: src/ENS.sol



// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface ENS {
    function owner(bytes32 node) external returns (address);
    function resolver(bytes32 node) external returns (Resolver);
    function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external;
    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external;
    function setOwner(bytes32 node, address owner) external;
    // for testing purposes
    function setApprovalForAll(address operator, bool approved) external;
}

interface Resolver {
    function addr(bytes32 node) external returns (address);
    function setAddr(bytes32 node, address a) external;
}