/*
 * 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.jena.irix;

import java.util.Objects;

import org.apache.jena.atlas.lib.IRILib;

/**
 * Operations in support of {@link IRIx}.
 */
public class IRIs {
    /**
     * Operation to take a string and make an {@link IRIx}.
     * This operation does not resolve the string against a base.
     * <p>
     * Use this function if the application has been given an URI
     * and wants to be sure it is valid for use in RDF.
     * <p>
     * Use {@link IRIs#resolve} to resolve a potentially relative URI against the current system base.
     */
    static public IRIx reference(String iriStr) {
        Objects.requireNonNull(iriStr);
        IRIx iri = IRIx.create(iriStr);
        if ( ! iri.isReference() )
            throw new IRIException("Not an RDF IRI: <"+iriStr+">");
        return iri;
    }

    /** Check a string is valid syntax for an IRI (absolute or relative) */
    static public boolean check(String iriStr) {
        Objects.requireNonNull(iriStr);
        try {
            checkEx(iriStr);
            return true;
        } catch(Exception ex) { return false; }
    }

    /**
     * Check a string is valid syntax for an IRI,
     * is an absolute IRI (resolve if necessary)
     * and normalize (e.g. remove "./.." and "/../").
     */
    static public String checkEx(String iriStr) {
        Objects.requireNonNull(iriStr);
        return reference(iriStr).str();
    }

    /** The system base {@link IRIx}. */
    public static IRIx getSystemBase() {
        return SystemIRIx.getSystemBase();
    }

    /** The system base IRI as a string. */
    public static String getBaseStr() {
        return SystemIRIx.getSystemBase().toString();
    }

    /**
     * Given a candidate baseURI string, which may be a filename,
     * turn it into a IRI suitable as a base IRI.
     */
    public static String toBase(String baseURI) {
        String scheme = scheme(baseURI);
        // Assume scheme of one letter are Windows drive letters.
        if ( scheme != null && scheme.length() == 1 )
            scheme = "file";
        if ( scheme != null && scheme.equals("file") )
            return IRILib.filenameToIRI(baseURI);
        return IRIs.getSystemBase().resolve(baseURI).toString();
    }

    /** Return a general purpose resolver, with the current system base as its base IRI. */
    public static IRIxResolver stdResolver() {
        return resolver(getSystemBase());
    }

    /** Return a general purpose resolver, with the current system base as its base IRI. */
    public static IRIxResolver resolver(String base) {
        return IRIxResolver.create(base).resolve(true).allowRelative(false).build();
    }

    /** Return a general purpose resolver, with the supplied IRI its base. */
    public static IRIxResolver resolver(IRIx base) {
        return IRIxResolver.create(base).resolve(true).allowRelative(false).build();
    }

    /** Return a resolver that does not resolve, and have a base and does not allow relative URIs. */
    public static IRIxResolver absoluteResolver() {
        return IRIxResolver.create().noBase().resolve(false).allowRelative(false).build();
    }

    /** Return a resolver that does not resolve relative URIs, with the current system base as its base IRI */
    public static IRIxResolver relativeResolver() {
        return IRIxResolver.create().noBase().resolve(false).allowRelative(true).build();
    }

    /** Resolve a URI against the system base. */
    public static String resolve(String iriStr) {
        if ( iriStr == null )
            return getSystemBase().str();
        return resolve(getSystemBase(), iriStr);
    }

    /** Resolve a URI against the system base. */
    public static IRIx resolveIRI(String iriStr) {
        if ( iriStr == null )
            return getSystemBase();
        return getSystemBase().resolve(iriStr);
    }

    /** Resolve a URI against a base. */
    public static String resolve(IRIx base, String iriStr) {
        return base.resolve(iriStr).str();
    }

    /** Resolve a URI against a base. */
    public static String resolve(IRIx base, IRIx iri) {
        return base.resolve(iri).str();
    }

    /** Resolve a URI against a base. The base must be an absolute IRI. */
    public static String resolve(String baseStr, String iriStr) {
        IRIx base = IRIx.create(baseStr);
        if ( ! base.isReference() )
            throw new IRIException("Not suitable as a base URI: '"+baseStr+"'");
        return resolve(base, iriStr);
    }

    /**
     * Get the URI scheme at the start of the string. This is the substring up to, and
     * excluding, the first ":" if it conforms to the syntax requirements. Return null
     * if it does not look like a scheme.
     * <p>
     * The <a href="https://tools.ietf.org/html/rfc3986#appendix-A">RFC 3986 URI
     * grammar</a> defines {@code scheme} as:
     *
     * <pre>
     * URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
     * scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
     * ...
     * </pre>
     */
    public static String scheme(String str) {
        int idx = scheme(str, 0);
        if ( idx <= 0 || idx > str.length())
            return null;
        return str.substring(0, idx);
    }

    // Return the index of the ":" starting from "start"
    // so that start to the returned index is the scheme including ":"
    // Return <= 0 for no scheme.
    // -1 Syntax error
    // 0 did not find a colon.
    private static int scheme(String str, int start) {
        int p = start;
        int end = str.length();
        while (p < end) {
            char c = str.charAt(p);
            if ( c == ':' )
                return p;
            if ( ! isAlpha(c) ) {
                if ( p == start )
                    // Bad first character
                    return -1;
                if ( ! ( isDigit(c) || c == '+' || c == '-' || c == '.' ) )
                    // Bad subsequent character
                    return -1;
            }
            p++;
        }
        // Did not find ':'
        return 0;
    }

    private static boolean isDigit(char ch) {
        return (ch >= '0' && ch <= '9');
    }

    private static boolean isAlpha(char ch) {
        return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
    }
}
