package org.gcube.application.geoportal.common.model.useCaseDescriptor;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import org.bson.Document;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.User;

import java.util.List;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class DataAccessPolicy {

    public static final String POLICY = "_policy";
    public static final String ROLES = "_roles";
    public static final String ENFORCER = "_enforcer";

    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    @Setter
    @ToString
    public static class Policy {
        public static final String WRITE="_write";
        public static final String READ="_read";

        public static enum Type{
            own, none, any
        }

        @JsonProperty(WRITE)
        private Type write;
        @JsonProperty(READ)
        private Type read;
    }


    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    @Setter
    @ToString
    public static class PolicyEnforcer {
        public static final String FILTER="_filter";
        @JsonProperty(FILTER)
        private String filter;

        @JsonIgnore
        public Document getFilterDocument(){
            if(filter!=null) return Document.parse(filter);
            else return new Document();
        }
    }


    @JsonProperty(POLICY)
    private Policy policy;
    @JsonProperty(ROLES)
    private List<String> roles;
    @JsonProperty(ENFORCER)
    private PolicyEnforcer enforcer;

    @JsonIgnore
    public boolean canRead(Project p, User u){
        switch(getPolicy().getRead()){
            case own: return p.getInfo().getCreationInfo().getUser().equals(u);
            case any: return true;
            case none:
            default : return false;
        }
    }

    @JsonIgnore
    public boolean canWrite(Project p, User u){
        switch(getPolicy().getWrite()){
            case own: return p.getInfo().getCreationInfo().getUser().equals(u);
            case any: return true;
            case none:
            default : return false;
        }
    }
}
