/*
 * Licensed to The OpenNMS Group, Inc (TOG) under one or more
 * contributor license agreements.  See the LICENSE.md file
 * distributed with this work for additional information
 * regarding copyright ownership.
 *
 * TOG licenses this file to You under the GNU Affero General
 * Public License Version 3 (the "License") or (at your option)
 * any later version.  You may not use this file except in
 * compliance with the License.  You may obtain a copy of the
 * License at:
 *
 *      https://www.gnu.org/licenses/agpl-3.0.txt
 *
 * 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.opennms.features.elastic.client.model;

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

/**
 * Represents the response from a bulk operation.
 */
public class BulkResponse {
    
    private final boolean hasErrors;
    private final List<BulkItemResponse> items;
    private final long tookInMillis;
    
    public BulkResponse(boolean hasErrors, List<BulkItemResponse> items, long tookInMillis) {
        this.hasErrors = hasErrors;
        this.items = items != null ? new ArrayList<>(items) : new ArrayList<>();
        this.tookInMillis = tookInMillis;
    }
    
    public boolean hasErrors() {
        return hasErrors;
    }
    
    public List<BulkItemResponse> getItems() {
        return items;
    }
    
    public long getTookInMillis() {
        return tookInMillis;
    }
    
    public List<BulkItemResponse> getFailedItems() {
        return items.stream()
                .filter(BulkItemResponse::isFailed)
                .toList();
    }
    
    public String getErrors() {
        StringBuilder errorBuilder = new StringBuilder();
        List<BulkItemResponse> failedItems = getFailedItems();
        if (!failedItems.isEmpty()) {
            errorBuilder.append("Bulk request failed with ").append(failedItems.size()).append(" errors:\n");
            for (int i = 0; i < Math.min(5, failedItems.size()); i++) {
                BulkItemResponse item = failedItems.get(i);
                errorBuilder.append("  [")
                        .append(item.getIndex())
                        .append("/")
                        .append(item.getId() != null ? item.getId() : "<auto-generated>")
                        .append("] ")
                        .append(item.getError())
                        .append("\n");
            }
            if (failedItems.size() > 5) {
                errorBuilder.append("  ... and ").append(failedItems.size() - 5).append(" more errors\n");
            }
        }
        return errorBuilder.toString();
    }
    
    public static class BulkItemResponse {
        private final String index;
        private final String id;
        private final int status;
        private final String error;
        private final boolean failed;
        
        public BulkItemResponse(String index, String id, int status, String error) {
            this.index = index;
            this.id = id;
            this.status = status;
            this.error = error;
            this.failed = status >= 400 || error != null;
        }
        
        public String getIndex() {
            return index;
        }
        
        public String getId() {
            return id;
        }
        
        public int getStatus() {
            return status;
        }
        
        public String getError() {
            return error;
        }
        
        public boolean isFailed() {
            return failed;
        }
    }
}