// Path: sqlsauce-core/src/main/java/space/npstr/sqlsauce/converters/PostgresHStoreConverter.java
// @Converter(autoApply = true)
// public class PostgresHStoreConverter implements AttributeConverter<Map<String, String>, String>, Serializable {
// 
//     private static final long serialVersionUID = 6734295028227191361L;
// 
//     @Override
//     public String convertToDatabaseColumn(@Nullable final Map<String, String> attribute) {
//         return HStoreConverter.toString(attribute != null ? attribute : new HashMap<>());
//     }
// 
//     @Override
//     public Map<String, String> convertToEntityAttribute(@Nullable final String dbData) {
//         if (dbData == null) {
//             return new HashMap<>();
//         }
//         return HStoreConverter.fromString(dbData);
//     }
// }
// 
// Path: discord-entities/src/main/java/space/npstr/sqlsauce/jda/listeners/CacheableUser.java
// public interface CacheableUser<S> extends Cacheable<S> {
// 
//     /**
//      * Set whatever values are necessary from a JDA user.
//      */
//     S set(User user);
// 
//     /**
//      * Set whatever values are necessary from a JDA member.
//      */
//     S set(Member member);
// }


import javax.annotation.Nullable;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.hibernate.annotations.ColumnDefault;
import space.npstr.sqlsauce.converters.PostgresHStoreConverter;
import space.npstr.sqlsauce.jda.listeners.CacheableUser;
/*
 * MIT License
 *
 * Copyright (c) 2017, Dennis Neufeld
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package space.npstr.sqlsauce.entities.discord;



/**
 * Created by napster on 17.10.17.
 * <p>
 * Base class for discord user entities. Best used in conjunction with a UserCachingListener.
 * Intended to provide a simple way to save user specific settings etc.
 * <p>
 * Attention: Unless you manually sync these entities between bot downtimes, there is no guarantee that the data is
 * consistent with reality. Consider this: A user changes their avatar while your bot is down (reconnecting, updating
 * whatever). Due to it being down, the change of the avatar is missed, so the avatarId field will contain an outdated
 * value.
 */
@MappedSuperclass
public abstract class DiscordUser<S extends BaseDiscordUser<S>> extends BaseDiscordUser<S> implements CacheableUser<S> {

    @Transient
    public static final String UNKNOWN_NAME = "Unknown User";

    @Column(name = "name", nullable = false, columnDefinition = "text")
    @ColumnDefault(value = UNKNOWN_NAME)
    protected String name = UNKNOWN_NAME;

    @Column(name = "discriminator", nullable = false)
    @ColumnDefault(value = "-1")
    protected short discriminator;

    @Nullable
    @Column(name = "avatar_id", nullable = true, columnDefinition = "text")
    protected String avatarId;

    @Column(name = "bot", nullable = false)
    @ColumnDefault(value = "false")
    protected boolean bot;

    @Column(name = "nicks", columnDefinition = "hstore")
// Path: sqlsauce-core/src/main/java/space/npstr/sqlsauce/converters/PostgresHStoreConverter.java
// @Converter(autoApply = true)
// public class PostgresHStoreConverter implements AttributeConverter<Map<String, String>, String>, Serializable {
// 
//     private static final long serialVersionUID = 6734295028227191361L;
// 
//     @Override
//     public String convertToDatabaseColumn(@Nullable final Map<String, String> attribute) {
//         return HStoreConverter.toString(attribute != null ? attribute : new HashMap<>());
//     }
// 
//     @Override
//     public Map<String, String> convertToEntityAttribute(@Nullable final String dbData) {
//         if (dbData == null) {
//             return new HashMap<>();
//         }
//         return HStoreConverter.fromString(dbData);
//     }
// }
// 
// Path: discord-entities/src/main/java/space/npstr/sqlsauce/jda/listeners/CacheableUser.java
// public interface CacheableUser<S> extends Cacheable<S> {
// 
//     /**
//      * Set whatever values are necessary from a JDA user.
//      */
//     S set(User user);
// 
//     /**
//      * Set whatever values are necessary from a JDA member.
//      */
//     S set(Member member);
// }


// Path: discord-entities/src/main/java/space/npstr/sqlsauce/entities/discord/DiscordUser.java
import javax.annotation.Nullable;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.hibernate.annotations.ColumnDefault;
import space.npstr.sqlsauce.converters.PostgresHStoreConverter;
import space.npstr.sqlsauce.jda.listeners.CacheableUser;

/*
 * MIT License
 *
 * Copyright (c) 2017, Dennis Neufeld
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package space.npstr.sqlsauce.entities.discord;



/**
 * Created by napster on 17.10.17.
 * <p>
 * Base class for discord user entities. Best used in conjunction with a UserCachingListener.
 * Intended to provide a simple way to save user specific settings etc.
 * <p>
 * Attention: Unless you manually sync these entities between bot downtimes, there is no guarantee that the data is
 * consistent with reality. Consider this: A user changes their avatar while your bot is down (reconnecting, updating
 * whatever). Due to it being down, the change of the avatar is missed, so the avatarId field will contain an outdated
 * value.
 */
@MappedSuperclass
public abstract class DiscordUser<S extends BaseDiscordUser<S>> extends BaseDiscordUser<S> implements CacheableUser<S> {

    @Transient
    public static final String UNKNOWN_NAME = "Unknown User";

    @Column(name = "name", nullable = false, columnDefinition = "text")
    @ColumnDefault(value = UNKNOWN_NAME)
    protected String name = UNKNOWN_NAME;

    @Column(name = "discriminator", nullable = false)
    @ColumnDefault(value = "-1")
    protected short discriminator;

    @Nullable
    @Column(name = "avatar_id", nullable = true, columnDefinition = "text")
    protected String avatarId;

    @Column(name = "bot", nullable = false)
    @ColumnDefault(value = "false")
    protected boolean bot;

    @Column(name = "nicks", columnDefinition = "hstore")
    @Convert(converter = PostgresHStoreConverter.class)