package com.example.struts2;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 文件上传Action - 演示Struts2文件上传功能
 * 
 * 学习点：
 * - 文件上传配置
 * - 多文件上传
 * - 文件类型和大小限制
 */
public class FileUploadAction extends ActionSupport {
    
    // 单文件上传字段
    private File upload;
    private String uploadFileName;
    private String uploadContentType;
    private String description;
    
    // 多文件上传字段
    private File[] uploads;
    private String[] uploadsFileName;
    private String[] uploadsContentType;
    
    // 上传结果
    private Map<String, Object> uploadResult;
    private String uploadedFilePath;
    
    // 上传目录
    private static final String UPLOAD_DIR = "/tmp/struts2-uploads/";
    
    /**
     * 显示上传页面
     */
    public String execute() {
        return SUCCESS;
    }
    
    /**
     * 处理单文件上传
     */
    public String uploadSingle() {
        uploadResult = new HashMap<>();
        
        if (upload == null) {
            uploadResult.put("success", false);
            uploadResult.put("error", "请选择要上传的文件");
            return SUCCESS;
        }
        
        try {
            // 创建上传目录
            File dir = new File(UPLOAD_DIR);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            
            // 生成唯一文件名
            String uniqueFileName = UUID.randomUUID().toString() + "_" + uploadFileName;
            File destFile = new File(dir, uniqueFileName);
            
            // 保存文件
            copyFile(upload, destFile);
            
            uploadedFilePath = destFile.getAbsolutePath();
            
            uploadResult.put("success", true);
            uploadResult.put("message", "文件上传成功");
            uploadResult.put("originalName", uploadFileName);
            uploadResult.put("savedName", uniqueFileName);
            uploadResult.put("fileSize", upload.length());
            uploadResult.put("contentType", uploadContentType);
            uploadResult.put("filePath", uploadedFilePath);
            uploadResult.put("description", description);
            
        } catch (Exception e) {
            uploadResult.put("success", false);
            uploadResult.put("error", "上传失败: " + e.getMessage());
        }
        
        return SUCCESS;
    }
    
    /**
     * 处理多文件上传
     */
    public String uploadMultiple() {
        uploadResult = new HashMap<>();
        
        if (uploads == null || uploads.length == 0) {
            uploadResult.put("success", false);
            uploadResult.put("error", "请选择要上传的文件");
            return SUCCESS;
        }
        
        Map<String, Object>[] files = new HashMap[uploads.length];
        int successCount = 0;
        
        try {
            File dir = new File(UPLOAD_DIR);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            
            for (int i = 0; i < uploads.length; i++) {
                Map<String, Object> fileInfo = new HashMap<>();
                
                if (uploads[i] != null) {
                    String uniqueFileName = UUID.randomUUID().toString() + "_" + uploadsFileName[i];
                    File destFile = new File(dir, uniqueFileName);
                    
                    copyFile(uploads[i], destFile);
                    
                    fileInfo.put("originalName", uploadsFileName[i]);
                    fileInfo.put("savedName", uniqueFileName);
                    fileInfo.put("fileSize", uploads[i].length());
                    fileInfo.put("contentType", uploadsContentType[i]);
                    fileInfo.put("success", true);
                    successCount++;
                } else {
                    fileInfo.put("success", false);
                    fileInfo.put("error", "文件为空");
                }
                
                files[i] = fileInfo;
            }
            
            uploadResult.put("success", true);
            uploadResult.put("message", "成功上传 " + successCount + " 个文件");
            uploadResult.put("totalFiles", uploads.length);
            uploadResult.put("successCount", successCount);
            uploadResult.put("files", files);
            
        } catch (Exception e) {
            uploadResult.put("success", false);
            uploadResult.put("error", "上传失败: " + e.getMessage());
        }
        
        return SUCCESS;
    }
    
    /**
     * 文件复制辅助方法
     */
    private void copyFile(File src, File dest) throws IOException {
        try (FileInputStream fis = new FileInputStream(src);
             FileOutputStream fos = new FileOutputStream(dest)) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
        }
    }
    
    @Override
    public void validate() {
        // 可以在这里添加文件大小和类型的验证
        if (upload != null) {
            // 限制文件大小为10MB
            if (upload.length() > 10 * 1024 * 1024) {
                addFieldError("upload", "文件大小不能超过10MB");
            }
            
            // 限制文件类型
            String[] allowedTypes = {"image/jpeg", "image/png", "image/gif", "application/pdf", "text/plain"};
            boolean allowed = false;
            for (String type : allowedTypes) {
                if (type.equals(uploadContentType)) {
                    allowed = true;
                    break;
                }
            }
            if (!allowed) {
                addFieldError("upload", "不支持的文件类型: " + uploadContentType);
            }
        }
    }
    
    // Getters and Setters
    public File getUpload() { return upload; }
    public void setUpload(File upload) { this.upload = upload; }
    
    public String getUploadFileName() { return uploadFileName; }
    public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; }
    
    public String getUploadContentType() { return uploadContentType; }
    public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; }
    
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    
    public File[] getUploads() { return uploads; }
    public void setUploads(File[] uploads) { this.uploads = uploads; }
    
    public String[] getUploadsFileName() { return uploadsFileName; }
    public void setUploadsFileName(String[] uploadsFileName) { this.uploadsFileName = uploadsFileName; }
    
    public String[] getUploadsContentType() { return uploadsContentType; }
    public void setUploadsContentType(String[] uploadsContentType) { this.uploadsContentType = uploadsContentType; }
    
    public Map<String, Object> getUploadResult() { return uploadResult; }
    public void setUploadResult(Map<String, Object> uploadResult) { this.uploadResult = uploadResult; }
    
    public String getUploadedFilePath() { return uploadedFilePath; }
    public void setUploadedFilePath(String uploadedFilePath) { this.uploadedFilePath = uploadedFilePath; }
}
