/*
 * 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) == ':';
  }
}
