/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.fineract.infrastructure.dataqueries.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.apache.commons.lang.StringUtils;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;

import com.google.gson.JsonArray;

@Entity
@Table(name = "stretchy_report", uniqueConstraints = { @UniqueConstraint(columnNames = { "report_name" }, name = "unq_report_name") })
public final class Report extends AbstractPersistableCustom<Long> {

    @Column(name = "report_name", nullable = false, unique = true)
    private String reportName;

    @Column(name = "report_type", nullable = false)
    private String reportType;

    @Column(name = "report_subtype")
    private String reportSubType;

    @Column(name = "report_category")
    private String reportCategory;

    @Column(name = "description")
    private String description;

    @Column(name = "core_report", nullable = false)
    private boolean coreReport;

    // only defines if report should appear in reference app UI List
    @Column(name = "use_report", nullable = false)
    private boolean useReport;

    @Column(name = "report_sql")
    private String reportSql;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "report", orphanRemoval = true, fetch=FetchType.EAGER)
    private Set<ReportParameterUsage> reportParameterUsages = new HashSet<>();
    
    @Column(name = "self_service_user_report")
    private boolean isSelfServiceUserReport;

    public static Report fromJson(final JsonCommand command, final Collection<String> reportTypes) {

        String reportName = null;
        String reportType = null;
        String reportSubType = null;
        String reportCategory = null;
        String description = null;
        boolean useReport = false;
        String reportSql = null;

        if (command.parameterExists("reportName")) {
            reportName = command.stringValueOfParameterNamed("reportName");
        }
        if (command.parameterExists("reportType")) {
            reportType = command.stringValueOfParameterNamed("reportType");
        }
        if (command.parameterExists("reportSubType")) {
            reportSubType = command.stringValueOfParameterNamed("reportSubType");
        }
        if (command.parameterExists("reportCategory")) {
            reportCategory = command.stringValueOfParameterNamed("reportCategory");
        }
        if (command.parameterExists("description")) {
            description = command.stringValueOfParameterNamed("description");
        }
        if (command.parameterExists("useReport")) {
            useReport = command.booleanPrimitiveValueOfParameterNamed("useReport");
        }
        if (command.parameterExists("reportSql")) {
            reportSql = command.stringValueOfParameterNamed("reportSql");
        }

        return new Report(reportName, reportType, reportSubType, reportCategory, description, useReport, reportSql, reportTypes);
    }

    protected Report() {
        //
    }

    public Report(final String reportName, final String reportType, final String reportSubType, final String reportCategory,
            final String description, final boolean useReport, final String reportSql, final Collection<String> reportTypes) {
        this.reportName = reportName;
        this.reportType = reportType;
        this.reportSubType = reportSubType;
        this.reportCategory = reportCategory;
        this.description = description;
        this.coreReport = false;
        this.useReport = useReport;
        this.reportSql = reportSql;
        validate(reportTypes);
    }

    public Map<String, Object> update(final JsonCommand command, final Collection<String> reportTypes) {

        final Map<String, Object> actualChanges = new LinkedHashMap<>(8);

        String paramName = "reportName";
        if (command.isChangeInStringParameterNamed(paramName, this.reportName)) {
            final String newValue = command.stringValueOfParameterNamed(paramName);
            actualChanges.put(paramName, newValue);
            this.reportName = StringUtils.defaultIfEmpty(newValue, null);
        }
        paramName = "reportType";
        if (command.isChangeInStringParameterNamed(paramName, this.reportType)) {
            final String newValue = command.stringValueOfParameterNamed(paramName);
            actualChanges.put(paramName, newValue);
            this.reportType = StringUtils.defaultIfEmpty(newValue, null);
        }
        paramName = "reportSubType";
        if (command.isChangeInStringParameterNamed(paramName, this.reportSubType)) {
            final String newValue = command.stringValueOfParameterNamed(paramName);
            actualChanges.put(paramName, newValue);
            this.reportSubType = StringUtils.defaultIfEmpty(newValue, null);
        }
        paramName = "reportCategory";
        if (command.isChangeInStringParameterNamed(paramName, this.reportCategory)) {
            final String newValue = command.stringValueOfParameterNamed(paramName);
            actualChanges.put(paramName, newValue);
            this.reportCategory = StringUtils.defaultIfEmpty(newValue, null);
        }
        paramName = "description";
        if (command.isChangeInStringParameterNamed(paramName, this.description)) {
            final String newValue = command.stringValueOfParameterNamed(paramName);
            actualChanges.put(paramName, newValue);
            this.description = StringUtils.defaultIfEmpty(newValue, null);
        }
        paramName = "useReport";
        if (command.isChangeInBooleanParameterNamed(paramName, this.useReport)) {
            final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(paramName);
            actualChanges.put(paramName, newValue);
            this.useReport = newValue;
        }
        paramName = "reportSql";
        if (command.isChangeInStringParameterNamed(paramName, this.reportSql)) {
            final String newValue = command.stringValueOfParameterNamed(paramName);
            actualChanges.put(paramName, newValue);
            this.reportSql = StringUtils.defaultIfEmpty(newValue, null);
        }

        final String reportParametersParamName = "reportParameters";
        if (command.hasParameter(reportParametersParamName)) {
            final JsonArray jsonArray = command.arrayOfParameterNamed(reportParametersParamName);
            if (jsonArray != null) {
                actualChanges.put(reportParametersParamName, command.jsonFragment(reportParametersParamName));
            }
        }

        validate(reportTypes);

        if (!actualChanges.isEmpty()) {
            if (isCoreReport()) {
                for (final String key : actualChanges.keySet()) {
                    if (!(key.equals("useReport"))) { throw new PlatformDataIntegrityException(
                            "error.msg.only.use.report.can.be.updated.for.core.report",
                            "Only the Use Report field can be updated for Core Reports", key); }
                }
            }
        }

        return actualChanges;
    }

    public boolean isCoreReport() {
        return this.coreReport;
    }

    public ReportParameterUsage findReportParameterById(final Long reportParameterId) {
        ReportParameterUsage reportParameterUsage = null;
        for (final ReportParameterUsage rpu : this.reportParameterUsages) {
            if (rpu.hasIdOf(reportParameterId)) {
                reportParameterUsage = rpu;
                break;
            }
        }
        return reportParameterUsage;
    }

    private void validate(final Collection<String> reportTypes) {

        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("report");

        baseDataValidator.reset().parameter("reportName").value(this.reportName).notBlank().notExceedingLengthOf(100);

        baseDataValidator.reset().parameter("reportType").value(this.reportType).notBlank().isOneOfTheseValues(reportTypes.toArray());

        baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType).notExceedingLengthOf(20);

        if (StringUtils.isNotBlank(this.reportType)) {
            if (this.reportType.equals("Chart")) {
                baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType)
                        .cantBeBlankWhenParameterProvidedIs("reportType", this.reportType)
                        .isOneOfTheseValues(new Object[] { "Bar", "Pie" });
            } else {
                baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType)
                        .mustBeBlankWhenParameterProvidedIs("reportType", this.reportType);
            }
        }

        baseDataValidator.reset().parameter("reportCategory").value(this.reportCategory).notExceedingLengthOf(45);

        if (StringUtils.isNotBlank(this.reportType)) {
            if ((this.reportType.equals("Table")) || (this.reportType.equals("Chart"))) {
                baseDataValidator.reset().parameter("reportSql").value(this.reportSql)
                        .cantBeBlankWhenParameterProvidedIs("reportType", this.reportType);
            } else {
                baseDataValidator.reset().parameter("reportSql").value(this.reportSql)
                        .mustBeBlankWhenParameterProvidedIs("reportType", this.reportType);
            }
        }
        throwExceptionIfValidationWarningsExist(dataValidationErrors);
    }

    private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
        if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
    }

    public String getReportName() {
        return this.reportName;
    }

    public boolean update(final Set<ReportParameterUsage> newReportParameterUsages) {
        if (newReportParameterUsages == null) { return false; }

        boolean updated = false;

        if (changeInReportParameters(newReportParameterUsages)) {
            updated = true;
            this.reportParameterUsages.clear();
            this.reportParameterUsages.addAll(newReportParameterUsages);
        }
        return updated;
    }

    private boolean changeInReportParameters(final Set<ReportParameterUsage> newReportParameterUsages) {

        if (!(this.reportParameterUsages.equals(newReportParameterUsages))) { return true; }

        return false;
    }
	
	public Set<ReportParameterUsage> getReportParameterUsages() {
		return this.reportParameterUsages;
	}

}