package com.caliverse.admin.logs.logservice.businesslogservice;

import java.util.List;
import java.util.ArrayList;

import lombok.Getter;
import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;
import org.springframework.data.mongodb.core.query.Criteria;

import com.caliverse.admin.global.common.constants.AdminConstants;


@Getter
public abstract class BusinessLogServiceBase implements IBusinessLogService {
    
    private MongoTemplate mongoTemplate;

    public BusinessLogServiceBase(MongoTemplate mongoTemplate){
        this.mongoTemplate = mongoTemplate;
    }

    //protected abstract Criteria makeCriteria(String startTime, String endTime);


    protected  AggregationOperation getDefaultProjectOperationRegex(){
        AggregationOperation projectOperation1 = context -> 
        new Document("$project",
            new Document(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE,
                new Document("$regexFind", 
                    new Document("input", "$message")
                        .append("regex", "\"LanguageType\":\"([^\"]+)\"")
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_MESSAGE, "$message")
            .append(AdminConstants.MONGO_DB_KEY_LOGTIME, "$logTime")
            .append(AdminConstants.MONGO_DB_KEY_USER_GUID,
                    new Document("$regexFind", 
                        new Document("input", "$message")
                            .append("regex", "\"UserGuid\":\"([^\"]+)\"")
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_USER_NICKNAME,
                    new Document("$regexFind",
                            new Document("input", "$message")
                                    .append("regex", "\"UserNickname\":\"([^\"]+)\"")
                    )
            )
            .append(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID,
                    new Document("$regexFind", 
                        new Document("input", "$message")
                            .append("regex", "\"AccountId\":\"([^\"]+)\"")
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_LOGIN_TIME,
                    new Document("$regexFind",
                        new Document("input", "$message")
                            .append("regex", "\"LoginTime\":\"([^\"]+)\"")
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_LOGOUT_TIME,
                    new Document("$regexFind",
                        new Document("input", "$message")
                            .append("regex", "\"LogoutTime\":\"([^\"]+)\"")
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_TRAN_ID,
                    new Document("$regexFind",
                        new Document("input", "$message")
                            .append("regex", "\"TranId\":\"([^\"]+)\"")
                    )
            )
            .append(AdminConstants.MONGO_DB_KEY_ACTION,
                    new Document("$regexFind",
                            new Document("input", "$message")
                                    .append("regex", "\"Action\":\"([^\"]+)\"")
                    )
            )
            .append(AdminConstants.MONGO_DB_KEY_DOMAIN,
                    new Document("$regexFind",
                            new Document("input", "$message")
                                    .append("regex", "\"Domain\":\"([^\"]+)\"")
                    )
            )
            .append(AdminConstants.MONGO_DB_KEY_SERVER_TYPE,
                    new Document("$regexFind",
                            new Document("input", "$message")
                                    .append("regex", "\"ServerType\":\"([^\"]+)\"")
                    )
            )
        );

        return projectOperation1;
    }


    protected  AggregationOperation getDefaultProjectOperationCapture(){
        AggregationOperation projectOperation2 = context -> 
        new Document("$project",
            new Document(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE,
                    new Document("$ifNull", List.of(
                        new Document("$toString", 
                            new Document("$arrayElemAt", List.of("$languageType.captures", 0))
                        ),
                        "Ko"
                    )
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_USER_GUID,
                new Document()
                    .append("$ifNull", List.of(
                        new Document("$toString", 
                            new Document("$arrayElemAt", List.of("$userGuid.captures", 0))
                        ),
                        "None"
                    )
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_USER_NICKNAME,
                    new Document()
                            .append("$ifNull", List.of(
                                            new Document("$toString",
                                                    new Document("$arrayElemAt", List.of("$userNickname.captures", 0))
                                            ),
                                            "None"
                                    )
                            )
            )
            .append(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID,
                new Document()
                    .append("$ifNull", List.of(
                        new Document("$toString", 
                            new Document("$arrayElemAt", List.of("$accountId.captures", 0))
                        ),
                        "None"
                    )
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_LOGIN_TIME,
                new Document()
                    .append("$ifNull", List.of(
                        new Document("$toString",
                            new Document("$arrayElemAt", List.of("$loginTime.captures", 0))
                        ),
                        ""
                    )
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_LOGOUT_TIME,
                new Document()
                    .append("$ifNull", List.of(
                        new Document("$toString",
                            new Document("$arrayElemAt", List.of("$logoutTime.captures", 0))
                        ),
                        ""
                    )
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_TRAN_ID,
                new Document()
                    .append("$ifNull", List.of(
                        new Document("$toString",
                            new Document("$arrayElemAt", List.of("$tranId.captures", 0))
                        ),
                        ""
                    )
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_ACTION,
                new Document()
                    .append("$ifNull", List.of(
                        new Document("$toString",
                            new Document("$arrayElemAt", List.of("$action.captures", 0))
                        ),
                        ""
                    )
                )
            )
            .append(AdminConstants.MONGO_DB_KEY_DOMAIN,
                new Document()
                    .append("$ifNull", List.of(
                        new Document("$toString",
                                new Document("$arrayElemAt", List.of("$domain.captures", 0))
                        ),
                        ""
                        )
                    )
            )
            .append(AdminConstants.MONGO_DB_KEY_SERVER_TYPE,
                new Document()
                    .append("$ifNull", List.of(
                            new Document("$toString",
                                new Document("$arrayElemAt", List.of("$serverType.captures", 0))
                            ),
                            ""
                        )
                    )
            )
            .append(AdminConstants.MONGO_DB_KEY_LOGTIME, "$logTime")
            .append(AdminConstants.MONGO_DB_KEY_LOGMONTH,
                    new Document("$substr" , List.of("$logTime", 0, 7)) //0000-00
            )
            .append(AdminConstants.MONGO_DB_KEY_LOGDAY,
                new Document("$substr" , List.of("$logTime", 0, 10)) //0000-00-00
            )
            .append(AdminConstants.MONGO_DB_KEY_LOGHOUR,
                new Document("$substr" , List.of("$logTime", 0, 13))
            )
            .append(AdminConstants.MONGO_DB_KEY_LOGMINUTE,
                new Document("$substr" , List.of("$logTime", 0, 16))
            )
            .append("message", "$message")
        );

        return projectOperation2;
    }
    private AggregationOperation getDefaultProjectOperationName(){
        ProjectionOperation projectOperation = Aggregation.project()
            .and(AdminConstants.MONGO_DB_KEY_LOGTIME).as(AdminConstants.MONGO_DB_KEY_LOGTIME)
            .and(AdminConstants.MONGO_DB_KEY_LOGMONTH).as(AdminConstants.MONGO_DB_KEY_LOGMONTH)
            .and(AdminConstants.MONGO_DB_KEY_LOGDAY).as(AdminConstants.MONGO_DB_KEY_LOGDAY)
            .and(AdminConstants.MONGO_DB_KEY_LOGHOUR).as(AdminConstants.MONGO_DB_KEY_LOGHOUR)
            .and(AdminConstants.MONGO_DB_KEY_LOGMINUTE).as(AdminConstants.MONGO_DB_KEY_LOGMINUTE)
            .and(AdminConstants.MONGO_DB_KEY_MESSAGE).as(AdminConstants.MONGO_DB_KEY_MESSAGE)
            .and(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE).as(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE)
            .and(AdminConstants.MONGO_DB_KEY_USER_GUID).as(AdminConstants.MONGO_DB_KEY_USER_GUID)
            .and(AdminConstants.MONGO_DB_KEY_USER_NICKNAME).as(AdminConstants.MONGO_DB_KEY_USER_NICKNAME)
            .and(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID).as(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID)
            .and(AdminConstants.MONGO_DB_KEY_LOGIN_TIME).as(AdminConstants.MONGO_DB_KEY_LOGIN_TIME)
            .and(AdminConstants.MONGO_DB_KEY_LOGOUT_TIME).as(AdminConstants.MONGO_DB_KEY_LOGOUT_TIME)
            .and(AdminConstants.MONGO_DB_KEY_TRAN_ID).as(AdminConstants.MONGO_DB_KEY_TRAN_ID)
            .and(AdminConstants.MONGO_DB_KEY_ACTION).as(AdminConstants.MONGO_DB_KEY_ACTION)
            .and(AdminConstants.MONGO_DB_KEY_DOMAIN).as(AdminConstants.MONGO_DB_KEY_DOMAIN)
            .and(AdminConstants.MONGO_DB_KEY_SERVER_TYPE).as(AdminConstants.MONGO_DB_KEY_SERVER_TYPE)
            .and("message").as("message")
        ;
        return projectOperation;
        
    }


    protected List<AggregationOperation> setDefaultOperation(Criteria criteria){

        List<AggregationOperation> operations = new ArrayList<>();
        
        operations.add(Aggregation.match(criteria));
        operations.add(getDefaultProjectOperationRegex());
        operations.add(getDefaultProjectOperationCapture());
        operations.add(getDefaultProjectOperationName());

        return operations;
    }

}

