package nc.bs.arap.impl;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import nc.bs.framework.adaptor.IHttpServletAdaptor;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.common.RuntimeEnv;
import nc.bs.framework.server.ISecurityTokenCallback;
import nc.bs.pub.filesystem.IFileSystemService;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.MapProcessor;
import nc.log.NcLog;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.codehaus.jettison.json.JSONException;

import com.alibaba.fastjson.JSONObject;

/**
 * 附件上传接口
 */
public class AttachmentUploadImpl implements IHttpServletAdaptor {
	private static IUAPQueryBS iuap = (IUAPQueryBS) NCLocator.getInstance().lookup(IUAPQueryBS.class.getName());
	private String filename = null;
	private InputStream inputstream = null;
	private String pk_zbresult = null;
	private String billmaker = null;
	private String vbillcode = null;
	private IFileSystemService service = NCLocator.getInstance().lookup(IFileSystemService.class);

	@Override
	public void doAction(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			req.setCharacterEncoding("UTF-8");
			resp.setContentType("text/json");
			resp.setCharacterEncoding("UTF-8");
			// 检查是否是多部分请求
			String contentType = req.getContentType();
			if (!(contentType != null && contentType.startsWith("multipart/"))) {
				resp.getWriter().write(formatRSJsonData("失败", "Content type is not multipart/form-data", "").toString());
				return;
			}
			NCLocator.getInstance().lookup(ISecurityTokenCallback.class).token("NCSystem".getBytes(), "pfxx".getBytes());
//			InvocationInfoProxy.getInstance().setUserDataSource("NC6337");
			this.vbillcode = req.getParameter("vbillcode");
			String pk_tradetype = req.getParameter("pkTradetype");
			// 根据单据号单据类型查询单据主键、billmaker
			Map<String, String> billMap = getDataMap(pk_tradetype,this.vbillcode);
			this.pk_zbresult = billMap.get("pk_zbresult");
			this.billmaker = billMap.get("billmaker");
			// 配置上传参数
			DiskFileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			// 解析请求的内容提取文件数据
			List<FileItem> items = upload.parseRequest(req);
			for (FileItem item : items) {
				if (item.getFieldName().startsWith("file")) {
					this.filename = new File(item.getName()).getName();
					byte[] fileContent = item.get();
					this.inputstream = new ByteArrayInputStream(fileContent);
					// 将附件下载到本地
					String workpath = RuntimeEnv.getInstance().getNCHome() + File.separator + "tianhua" + File.separator + this.pk_zbresult + File.separator;
					File defaultDirectory = new File(workpath);
					if (!defaultDirectory.exists()) {
						// 不存在自动创建文件夹
						defaultDirectory.mkdirs();
					} else {
						// 清空缓存文件
						File[] oldfiles = defaultDirectory.listFiles();
						if (oldfiles.length > 0) {
							for (File file : oldfiles) {
								file.delete();
							}
						}
					}
					String ouputpath = workpath + this.filename;
					File target = new File(ouputpath);
					FileOutputStream fileoutputstream = new FileOutputStream(target);
					BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileoutputstream);
					byte[] buffer = new byte[1024];
					int bytesRead;
					while ((bytesRead = this.inputstream.read(buffer)) != -1) {
						// 将读取到的数据写入输出流
						bufferedOutputStream.write(buffer, 0, bytesRead);
					}
					bufferedOutputStream.flush();
					 //直接调用文件服务器接口 平台提供的默认本地上传方法，文件从客户端直接调用文件服务器插件上传。
					new FileInputStream(ouputpath);
					// 附加名称
					String fileName = new File(item.getName()).getName();
					InputStream inputStream = new ByteArrayInputStream(fileContent);
					// 调用附件保存接口
					service.createNewFileNodeWithStream(this.pk_zbresult, fileName, this.billmaker, inputStream, item.getSize());
					this.inputstream.close();
				}
			}
			resp.getWriter().write(formatRSJsonData("成功", "", this.vbillcode).toString());
			return;
		} catch (Exception e) {
			resp.getWriter().write(formatRSJsonData("失败", e.getMessage() == null ? "" : e.getMessage(), this.vbillcode).toString());
			StringWriter stringWriter = new StringWriter();
			e.printStackTrace(new PrintWriter(stringWriter));
			// 获取详细信息
			String msg = stringWriter.getBuffer().toString();
			NcLog.info("附件上传:" + msg);
			return;
		}
	}

	
	/**
	 * 格式返回json数据
	 * @return
	 * @throws JSONException
	 * @throws Exception
	 */
	public static JSONObject formatRSJsonData(String status, String error, String message) {
		JSONObject rs = new JSONObject();
		rs.put("status", status);
		rs.put("message", message);
		rs.put("error", error);
		return rs;
	}

	
	public Map<String, String> getDataMap(String type, String vbillcode) throws Exception {
		if ("".equals(vbillcode)) {
			return null;
		}
		Map<String, String> map = new HashMap<String, String>();
		String sql = "";
		if ("F3-Cxx-04".equals(type)) {
			sql = "select pk_paybill as pk_zbresult ,billmaker from ap_paybill where billno = '" + vbillcode + "' and nvl(dr,0) = 0";
			map = (Map<String, String>) iuap.executeQuery(sql.toString(),new MapProcessor());
			if (map == null) {
				throw new Exception("获取对外预付款(非项目)信息失败,未找到与参数" + vbillcode + "有关的数据！");
			}
		} else if ("F3-Cxx-05".equals(type)) {
			sql = "select pk_paybill as pk_zbresult ,billmaker from ap_paybill where billno ='" + vbillcode + "' and nvl(dr,0) = 0";
			map = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
			if (map == null) {
				throw new Exception("获取对外预付款(项目)信息失败,未找到与参数" + vbillcode + "有关的数据！");
			}
		}else if ("25".equals(type)) {
			sql = "select pk_invoice as pk_zbresult ,billmaker from po_invoice where vbillcode = '"+vbillcode+"' and nvl(dr,0) = 0";
			map = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
			if (map == null) {
				throw new Exception("获取采购发票信息失败,未找到与参数" + vbillcode + "有关的数据！");
			}
		}else if ("21".equals(type)) {
			sql = "select pk_order as pk_zbresult ,billmaker  from po_order where vbillcode = '"+vbillcode+"' and nvl(dr,0) = 0";
			map = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
			if (map == null) {
				throw new Exception("获取采购订单信息失败,未找到与参数" + vbillcode + "有关的数据！");
			}
		}else if ("D1".equals(type)) {
			sql = "select pk_payablebill as pk_zbresult ,billmaker from ap_payablebill where billno = '"+vbillcode+"' and nvl(dr,0) = 0";
			map = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
			if (map == null) {
				throw new Exception("获取应付单(非项目)信息失败,未找到与参数" + vbillcode + "有关的数据！");
			}
		}else if ("F1-Cxx-02".equals(type)) {
			sql = "select pk_payablebill as pk_zbresult ,billmaker from ap_payablebill where billno = '"+vbillcode+"' and nvl(dr,0) = 0";
			map = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
			if (map == null) {
				throw new Exception("获取应付单(项目)信息失败,未找到与参数" + vbillcode + "有关的数据！");
			}
		}
		else if ("F1-Cxx-04".equals(type)) {
			sql = "select pk_payablebill as pk_zbresult ,billmaker from ap_payablebill where billno = '"+vbillcode+"' and nvl(dr,0) = 0";
			map = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
			if (map == null) {
				throw new Exception("获取预付核销(非项目)信息失败,未找到与参数" + vbillcode + "有关的数据！");
			}
		}
		else if ("F1-Cxx-05".equals(type)) {
			sql = "select pk_payablebill as pk_zbresult ,billmaker from ap_payablebill where billno = '"+vbillcode+"' and nvl(dr,0) = 0";
			map = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
			if (map == null) {
				throw new Exception("获取预付核销(项目)信息失败,未找到与参数" + vbillcode + "有关的数据！");
			}
		}
		return map;
	}

}
