package pond.web;


import pond.common.S;
import pond.web.http.Cookie;
import pond.web.http.HttpUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * event
 *
 * @author ed
 */
public interface Request {

  String method();

  String remoteIp();

  InputStream in();

  String uri();

  Map<String, List<String>> headers();

  Map<String, List<String>> params();

  Map<String, List<UploadFile>> files();

  Map<String, Cookie> cookies();

  default String path() {
    return S._try_ret(() -> new URI(uri()).getPath());
  }

  default Cookie cookie(String s) {
    return cookies().get(s);
  }

  default List<String> headers(String string) {
    return headers().get(string);
  }

  default String header(String string) {
    return S._for(headers(string)).first();
  }

  default List<String> params(String para) {
    return params().get(para);
  }

  default String param(String para) {
    return S._for(params(para)).first();
  }

  default void param(String key, String val) {
    HttpUtils.appendToMap(params(), key, val);
  }

  //upload File
  default List<UploadFile> files(String file) {
    return files().get(file);
  }

  default UploadFile file(String file) {
    return S._for(files(file)).first();
  }

  default Integer paramInt(String para) {
    return S._try_ret(() -> Integer.parseInt(param(para)));
  }

  default Boolean paramBool(String para) {
    return S._try_ret(() -> Boolean.parseBoolean(param(para)));
  }

  default Double paramDouble(String para) {
    return S._try_ret(() -> Double.parseDouble(param(para)));
  }

  default Long paramLong(String para) {
    return S._try_ret(() -> Long.parseLong(param(para)));
  }

  default WebCtx ctx() {
    throw new RuntimeException("please implement the default Request#ctx() function");
  }

  /**
   * Returns all params as a Map
   */
  default Map<String, Object> toMap() {
    Map<String, Object> ret = new HashMap<>();
    //ret.putAll(S._for(attrs()).map(attr -> S._for(attr).limit()).val());
    ret.putAll(S._for(params()).map(param -> S._for(param).first()).val());
    return ret;
  }

  interface UploadFile {
    /**
     * attr name
     */
    String name();

    /**
     * original filename provided by client
     */
    String filename();

    /**
     * input for file
     */
    InputStream inputStream() throws IOException;

    /**
     * File
     */
    File file() throws IOException;

  }


}

@@ -1012,38 +1012,43 @@
 ing para) %7B%0A    
-return
+String a = 
  S._for(params(p
@@ -1054,32 +1054,151 @@
 para)).first();%0A
+    if(a == null %7C%7C %22%22.equals(a) %7C%7C %22null%22.equals(a) %7C%7C %22undefined%22.equals(a))%7B%0A      return null;%0A    %7D%0A    return a;%0A
   %7D%0A%0A  default v
@@ -1504,32 +1504,66 @@
 (String para) %7B%0A
+    if(para == null) return null;%0A
     return S._tr
@@ -1646,32 +1646,66 @@
 (String para) %7B%0A
+    if(para == null) return null;%0A
     return S._tr
@@ -1793,32 +1793,66 @@
 (String para) %7B%0A
+    if(para == null) return null;%0A
     return S._tr
@@ -1894,32 +1894,32 @@
 m(para)));%0A  %7D%0A%0A
-
   default Long p
@@ -1934,32 +1934,66 @@
 (String para) %7B%0A
+    if(para == null) return null;%0A
     return S._tr

add Request#paramX