package leigh.chain.directory;

import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;

import java.io.Serial;
import java.io.Serializable;
import java.time.Instant;
import java.util.HashMap;
import java.util.Set;

/**
 * This class implements the {@link DirectoryStore} interface using in-memory storage.
 *
 * @author Alex Leigh
 */
public class RamDirectoryStore implements DirectoryStore, Serializable {
    @Serial
    private static final long serialVersionUID = 0L;
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(RamDirectoryStore.class);

    private final HashMap<String, Identity> nameIdx = new HashMap<>();
    private final HashMap<String, Identity> addrIdx = new HashMap<>();

    public Set<String> getNames() {
        return nameIdx.keySet();
    }

    @Override
    public Identity getIdentityByName(String name, Instant when) {
        // TODO: Locale
        String lowerName = name.toLowerCase();

        Identity id = nameIdx.get(lowerName);

        if (id == null) return null;

        if (!id.isNameClaimValid(when)) {
            nameIdx.remove(lowerName);
            return null;
        }
        return id;
    }

    @Override
    public Identity getIdentityByAddr(String address) {
        return addrIdx.get(address);
    }

    public void putIdentity(Identity id) {
        logger.info("Storing new identity: {}", id);
        addrIdx.put(id.getAddress(), id);
        String nm = id.getName();
        if (nm != null) {
            // TODO: Locale?
            nameIdx.put(nm.toLowerCase(), id);
        }
    }

    @Override
    public void removeName(String name) {
        nameIdx.remove(name);
    }

    @Override
    public String toString() {
        return "RamDirectoryStore{" +
                "nameIdx=" + nameIdx +
                ", addrIdx=" + addrIdx +
                '}';
    }
}