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

contract Storage {
    struct User {
        uint256 feePaid; // total fees paid
        uint256 size; // current font size
        uint256 current; // current domain
        uint256 color; // current color
    }

    struct Domain {
        address owner;
        string name; // domain name (normalized)
    }

    mapping(address => User) public users;
    mapping(uint256 => Domain) public domains;
    mapping(address => bool) allow;

    address _owner;

    constructor() {
        _owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == _owner);
        _;
    }

    function getUser(address _user) public view returns (User memory user) {
        return users[_user];
    }

    function getDomain(uint256 _tokenId) public view returns (Domain memory domain) {
        return domains[_tokenId];
    }

    function setOwner(address __owner) public onlyOwner {
        _owner = __owner;
    }

    function add(address _nft) public onlyOwner {
        allow[_nft] = true;
    }

    function remove(address _nft) public onlyOwner {
        allow[_nft] = false;
    }

    function setSize(address _user, uint256 _size) public {
        require(allow[msg.sender], "[db] not allowed");
        users[_user].size = _size;
    }
    
    function setColor(address _user, uint256 _color) public {
        require(allow[msg.sender], "[db] not allowed");
        users[_user].color = _color;
    }

    function mint(
        string calldata label,
        address _user,
        uint256 tokenId,
        uint256 feesPaid
    ) external {
        require(allow[msg.sender], "[db] not allowed");
        if (users[_user].current != 0) domains[users[_user].current].owner = address(0);
        domains[tokenId] = Domain(_user, label);
        if (users[_user].size == 0) users[_user].size = 256;
        users[_user].feePaid += feesPaid;
        users[_user].current = tokenId;
        assert(domains[tokenId].owner == _user);
        assert(users[_user].current == tokenId);
    }
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"_nft","type":"address"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"domains","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getDomain","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct Storage.Domain","name":"domain","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUser","outputs":[{"components":[{"internalType":"uint256","name":"feePaid","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"color","type":"uint256"}],"internalType":"struct Storage.User","name":"user","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"feesPaid","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nft","type":"address"}],"name":"remove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_color","type":"uint256"}],"name":"setColor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"users","outputs":[{"internalType":"uint256","name":"feePaid","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"color","type":"uint256"}],"stateMutability":"view","type":"function"}]