package peruncs.eclipsestore.core;

import org.eclipse.store.gigamap.types.BinaryIndexerLong;
import org.eclipse.store.gigamap.types.BinaryIndexerString;
import org.eclipse.store.gigamap.types.GigaMap;

import java.util.Objects;

public class GigaMapTest {

     interface UserIdentityAttribute<T> {
        T id();
        User user();
    }


    record User (Long id, String name) implements UserIdentityAttribute<Long> {
        User{
            Objects.requireNonNull(id, "id is null");
            Objects.requireNonNull(name, "name is null");
        }
        @Override
        public User user() {return this;}
    }

    record Email(String emailAddress, User user) implements UserIdentityAttribute<String> {
        Email{
            Objects.requireNonNull(emailAddress, "email is null");
            Objects.requireNonNull(user, "user is null");
        }
        @Override
        public String id() {return emailAddress;}
    }

    private static final BinaryIndexerLong <UserIdentityAttribute<?>> USER_ID_INDEXER = new BinaryIndexerLong.Abstract<>() {
        @Override
        protected Long getLong(UserIdentityAttribute<?> userIdentityAttribute) {
            return userIdentityAttribute instanceof User user ? user.id() : userIdentityAttribute.user().id();
        }
    };

    private static final BinaryIndexerString<UserIdentityAttribute<?>> EMAIL_INDEXER = new BinaryIndexerString.Abstract<>() {
        @Override
        protected String getString(UserIdentityAttribute<?> userIdentityAttribute) {
            return userIdentityAttribute instanceof Email email? email.emailAddress(): null;
        }
    };


    static void main (String ... args) {


        var gigaMap =  GigaMap.<UserIdentityAttribute<?>>Builder()
                .withBitmapIndex(USER_ID_INDEXER)
                .withBitmapUniqueIndex(EMAIL_INDEXER)
                .build();

        var user = new User(1L,"Joe Doe");
        var email = new Email("joe.doe.@mail.com",user);

        gigaMap.add(user);
        gigaMap.add(email);
        assert gigaMap.size()==2;

        boolean emailRemovalResult = gigaMap.remove(email, EMAIL_INDEXER) != -1;
        assert emailRemovalResult;

        emailRemovalResult = gigaMap.remove(user, USER_ID_INDEXER) != -1;
        assert !emailRemovalResult;

        assert gigaMap.size()==1;


    }



}
