/*
 * 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.servicecomb.provider.springmvc.reference;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.servicecomb.common.rest.RestConst;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

/**
 * 默认不支持下面第1个场景，需要做出修正
 * cse://app:ms/path to cse://app/ms/path
 * cse://ms/path to cse://ms/path
 */
@SuppressWarnings("deprecation")
// TODO : upgrade to spring 5 will having warning's , we'll fix it later
public class CseUriTemplateHandler extends org.springframework.web.util.DefaultUriTemplateHandler {
  private static final String SCHEME_PATTERN = "([^:/?#]+):";

  private static final String USERINFO_PATTERN = "([^@\\[/?#]*)";

  private static final String HOST_IPV4_PATTERN = "[^\\[/?#:]*";

  private static final String HOST_IPV6_PATTERN = "\\[[\\p{XDigit}\\:\\.]*[%\\p{Alnum}]*\\]";

  private static final String HOST_PATTERN = "(" + HOST_IPV6_PATTERN + "|" + HOST_IPV4_PATTERN + ")";

  private static final String PORT_PATTERN = "(\\d*(?:\\{[^/]+?\\})?)";

  private static final String PATH_PATTERN = "([^?#]*)";

  private static final String QUERY_PATTERN = "([^#]*)";

  private static final String LAST_PATTERN = "(.*)";

  // Regex patterns that matches URIs. See RFC 3986, appendix B
  private static final Pattern URI_PATTERN = Pattern.compile(
      "^(" + SCHEME_PATTERN + ")?" + "(//(" + USERINFO_PATTERN + "@)?" + HOST_PATTERN + "(:" + PORT_PATTERN +
          ")?" + ")?" + PATH_PATTERN + "(\\?" + QUERY_PATTERN + ")?" + "(#" + LAST_PATTERN + ")?");

  public CseUriTemplateHandler() {
    setStrictEncoding(true);
  }

  @Override
  protected URI expandInternal(String uriTemplate, Map<String, ?> uriVariables) {
    UriComponentsBuilder uriComponentsBuilder = initUriComponentsBuilder(uriTemplate);
    UriComponents uriComponents = expandAndEncode(uriComponentsBuilder, uriVariables);
    return createUri(uriTemplate, uriComponents);
  }

  @Override
  protected URI expandInternal(String uriTemplate, Object... uriVariables) {
    UriComponentsBuilder uriComponentsBuilder = initUriComponentsBuilder(uriTemplate);
    UriComponents uriComponents = expandAndEncode(uriComponentsBuilder, uriVariables);
    return createUri(uriTemplate, uriComponents);
  }

  @Override
  protected UriComponentsBuilder initUriComponentsBuilder(String uriTemplate) {
    UriComponentsBuilder builder = fromUriString(uriTemplate);
    if (shouldParsePath() && !isStrictEncoding()) {
      List<String> pathSegments = builder.build().getPathSegments();
      builder.replacePath(null);
      for (String pathSegment : pathSegments) {
        builder.pathSegment(pathSegment);
      }
    }
    return builder;
  }

  private static UriComponentsBuilder fromUriString(String uri) {
    Assert.notNull(uri, "URI must not be null");
    Matcher matcher = URI_PATTERN.matcher(uri);
    if (matcher.matches()) {
      UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
      String scheme = matcher.group(2);
      String userInfo = matcher.group(5);
      String host = matcher.group(6);
      String port = matcher.group(8);
      String path = matcher.group(9);
      String query = matcher.group(11);
      String fragment = matcher.group(13);
      boolean opaque = false;
      if (StringUtils.hasLength(scheme)) {
        String rest = uri.substring(scheme.length());
        if (!rest.startsWith(":/")) {
          opaque = true;
        }
      }
      builder.scheme(scheme);
      if (opaque) {
        String ssp = uri.substring(scheme.length()).substring(1);
        if (StringUtils.hasLength(fragment)) {
          ssp = ssp.substring(0, ssp.length() - (fragment.length() + 1));
        }
        builder.schemeSpecificPart(ssp);
      } else {
        builder.userInfo(userInfo);
        builder.host(host);
        if (StringUtils.hasLength(port)) {
          builder.port(port);
        }
        builder.path(path);
        builder.query(query);
      }
      if (StringUtils.hasText(fragment)) {
        builder.fragment(fragment);
      }
      return builder;
    } else {
      throw new IllegalArgumentException("[" + uri + "] is not a valid URI");
    }
  }

  private URI createUri(String uriTemplate, UriComponents uriComponents) {
    String strUri = uriComponents.toUriString();

    Matcher matcher = URI_PATTERN.matcher(uriTemplate);
    matcher.matches(); // should always be true
    String scheme = matcher.group(2);
    String host = matcher.group(6);

    if (isCrossApp(uriTemplate, scheme, host)) {
      int idx;
      if (RestConst.SCHEME.equals(scheme)) {
        idx = strUri.indexOf('/', RestConst.URI_PREFIX.length());
      } else {
        idx = strUri.indexOf('/', RestConst.URI_PREFIX_NEW.length());
      }
      strUri = strUri.substring(0, idx) + ":" + strUri.substring(idx + 1);
    }

    try {
      // Avoid further encoding (in the case of strictEncoding=true)
      return new URI(strUri);
    } catch (URISyntaxException ex) {
      throw new IllegalStateException("Could not create URI object: " + ex.getMessage(), ex);
    }
  }

  private boolean isCrossApp(String uriTemplate, String scheme, String host) {
    int pos;
    if (RestConst.SCHEME.equals(scheme)) {
      pos = RestConst.URI_PREFIX.length() + host.length();
    } else {
      pos = RestConst.URI_PREFIX_NEW.length() + host.length();
    }

    return uriTemplate.charAt(pos) == ':';
  }
}
