/*
 * 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.dubbo.admin.common;

import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.admin.common.util.CoderUtil;
import org.apache.dubbo.admin.common.util.Constants;
import org.apache.dubbo.admin.model.domain.User;
import org.apache.dubbo.admin.service.UserService;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LoginFilter implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class);
    private static Pattern PARAMETER_PATTERN = Pattern.compile("(\\w+)=[\"]?([^,\"]+)[\"]?[,]?\\s*");
    private static final String BASIC_CHALLENGE = "Basic";
    private static final String DIGEST_CHALLENGE = "Digest";
    private static final String CHALLENGE = BASIC_CHALLENGE;
    private static final String REALM = User.REALM;

    @Autowired
    private UserService userService;
    private String logout = "/api/dev/logout";
    private String logoutCookie = "logout";



    static Map<String, String> parseParameters(String query) {
        Matcher matcher = PARAMETER_PATTERN.matcher(query);
        Map<String, String> map = new HashMap<String, String>();
        while (matcher.find()) {
            String key = matcher.group(1);
            String value = matcher.group(2);
            map.put(key, value);
        }
        return map;
    }

    static byte[] readToBytes(InputStream in) throws IOException {
        byte[] buf = new byte[in.available()];
        in.read(buf);
        return buf;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse) response;
        if (logger.isInfoEnabled()) {
            logger.info("AuthorizationValve of uri: " + req.getRequestURI());
        }
        String uri = req.getRequestURI();
        String contextPath = req.getContextPath();
        if (contextPath != null && contextPath.length() > 0 && !"/".equals(contextPath)) {
            uri = uri.substring(contextPath.length());
        }
        if (uri.equals(logout)) {
            if (!isLogout(req)) {
                setLogout(true, resp);
                showLoginForm(resp);
            } else {
                setLogout(false, resp);
//                resp.sendRedirect(contextPath == null || contextPath.length() == 0 ? "/" : contextPath);
            }
            return;
        }
        User user = null;
        String authType = null;
        String authorization = req.getHeader("Authorization");
        if (authorization != null && authorization.length() > 0) {
            int i = authorization.indexOf(' ');
            if (i >= 0) {
                authType = authorization.substring(0, i);
                String authPrincipal = authorization.substring(i + 1);
                if (BASIC_CHALLENGE.equalsIgnoreCase(authType)) {
                    user = loginByBase(authPrincipal);
                } else if (DIGEST_CHALLENGE.equalsIgnoreCase(authType)) {
                    user = loginByDigest(authPrincipal, req);
                }
            }
        }
        if (user == null || user.getUsername() == null || user.getUsername().length() == 0) {
            showLoginForm(resp);
            return;
            //pipelineContext.breakPipeline(1);
        }
        if (user != null && StringUtils.isNotEmpty(user.getUsername())) {
            req.getSession().setAttribute("currentUser", user);
            chain.doFilter(request, response);
        }

    }

    @Override
    public void destroy() {

    }

    private void showLoginForm(HttpServletResponse response) throws IOException {
        if (DIGEST_CHALLENGE.equals(CHALLENGE)) {
            response.setHeader("WWW-Authenticate", CHALLENGE + " realm=\"" + REALM + "\", qop=\"auth\", nonce=\""
                    + UUID.randomUUID().toString().replace("-", "") + "\", opaque=\""
                    + CoderUtil.MD5_32bit(REALM) + "\"");
        } else {
            response.setHeader("WWW-Authenticate", CHALLENGE + " realm=\"" + REALM + "\"");
        }
        response.setHeader("Cache-Control", "must-revalidate,no-cache,no-store");
        response.setHeader("Content-Type", "text/html; charset=iso-8859-1");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }

    private User getUser(String username) {
        return userService.findUser(username);
    }

    private User loginByBase(String authorization) {
        authorization = CoderUtil.decodeBase64(authorization);
        int i = authorization.indexOf(':');
        String username = authorization.substring(0, i);
        if (username != null && username.length() > 0) {
            String password = authorization.substring(i + 1);
            if (password != null && password.length() > 0) {
                String passwordDigest = CoderUtil.MD5_32bit(username + ":" + REALM + ":" + password);
                User user = getUser(username);
                if (user != null) {
                    String pwd = user.getPassword();
                    if (pwd != null && pwd.length() > 0) {
                        if (passwordDigest.equals(pwd)) {
                            return user;
                        }
                    }
                }
            }
        }
        return null;
    }

    private User loginByDigest(String value, HttpServletRequest request) throws IOException {
        Map<String, String> params = parseParameters(value);
        String username = params.get("username");
        if (username != null && username.length() > 0) {
            String passwordDigest = params.get("response");
            if (passwordDigest != null && passwordDigest.length() > 0) {
                User user = getUser(username);
                if (user != null) {
                    String pwd = user.getPassword();
                    // A valid user, validate password
                    if (pwd != null && pwd.length() > 0) {
                        String uri = params.get("uri");
                        String nonce = params.get("nonce");
                        String nc = params.get("nc");
                        String cnonce = params.get("cnonce");
                        String qop = params.get("qop");
                        String method = request.getMethod();
                        String a1 = pwd;

                        String a2 = "auth-int".equals(qop)
                                ? CoderUtil.MD5_32bit(method + ":" + uri + ":" + CoderUtil.MD5_32bit(readToBytes(request.getInputStream())))
                                : CoderUtil.MD5_32bit(method + ":" + uri);
                        String digest = "auth".equals(qop) || "auth-int".equals(qop)
                                ? CoderUtil.MD5_32bit(a1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + a2)
                                : CoderUtil.MD5_32bit(a1 + ":" + nonce + ":" + a2);
                        if (digest.equals(passwordDigest)) {
                            return user;
                        }
                    }
                }
            }
        }
        return null;
    }

    private boolean isLogout(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if (cookie != null && logoutCookie.equals(cookie.getName())) {
                    return "true".equals(cookie.getValue());
                }
            }
        }
        return false;
    }

    private void setLogout(boolean logoutValue, HttpServletResponse response) {
        response.addCookie(new Cookie(logoutCookie, String.valueOf(logoutValue)));
    }
}
