/*
 * 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 java.util.Optional;

import org.apache.jena.atlas.lib.Cache;
import org.apache.jena.atlas.lib.CacheFactory;

/**
 * A resolver is a base IRI and a policy for resolution. The policy choices are
 * whether to resolve against the base, or only consider the IRI being processed, and
 * whether to allow relative IRIs or to enforce that "base resolve IRI" is an
 * acceptable IRI for use in RDF (the test is {@link IRIx#isReference()}).
 * <p>
 * Normal use is to resolve and not allow relative IRIs.
 * <p>
 * The base may be null to support passing around a resolver that accepts/reject
 * IRIs. For application to check IRIs, use {@link IRIs#check}/{@link IRIs#checkEx}
 * directly.
 */
public class IRIxResolver {

    private final IRIx base;
    private final boolean resolve;
    private final boolean allowRelative;

    private IRIxResolver(IRIx base, boolean resolve, boolean allowRelative) {
        this.base = base;
        this.resolve = resolve;
        this.allowRelative = allowRelative;
    }

    /** Return the base of this resolver */
    public IRIx getBase() { return base; }

    /** Return the base of this resolver as a string */
    public String getBaseURI() { return base == null ? null : base.str(); }

    /*
     * Some providers are expensive compared to the cost of parsing.
     * During parsing a lot of IRIs are being created, many the same. For example,
     * e.g. properties or blocks of triples with the same subject.
     */
    private static int DftCacheSize = 500;
    private Cache<String, IRIx> cache = CacheFactory.createCache(DftCacheSize);

    /** Resolve the argument URI string according to resolver policy */
    public IRIx resolve(String other) {
        Objects.requireNonNull(other);
        if ( cache == null )
            return resolve0(other);

        // To allow for exceptions, we try the cache, and if no hit,
        // make the result then try again to fill the cache.
        // Because for a given key there is one right answer, it does not matter
        // if any thread gets in and changes the cache (cache operations are
        // thread safe).

        IRIx iri = cache.getIfPresent(other);
        if ( iri != null )
            return iri;
        // May throw an exception
        IRIx iriValue = resolve0(other);
        return cache.getOrFill(other, ()->iriValue);
    }

    private IRIx resolve0(String str) {
        IRIx x = (base != null && resolve)
                ? base.resolve(str)
                : IRIx.create(str);
        if ( ! allowRelative && x.isRelative() )
            throw new RelativeIRIException("Relative IRI: <"+str+">");
        return x;
    }

    /** Create a new resolver with the same policies as the old one. */
    public IRIxResolver resetBase(IRIx newBase) {
        return new IRIxResolver(newBase, resolve, allowRelative);
    }

    @Override
    public String toString() {
        return "IRIxResolver[base=" + base + ", resolve=" + resolve + ", relative=" + allowRelative+"]";
    }

   public static Builder create() { return new Builder(); }

   /**
    * Create a {@link IRIxResolver} with the base URI which is resolved against the
    * current system default base.
    */
   public static Builder create(IRIxResolver original) {
       Builder builder = new Builder();
       builder.base = Optional.ofNullable(original.base);
       builder.resolve = original.resolve;
       builder.allowRelative = original.allowRelative;
       return builder;
   }

   /**
    * Create a builder for a {@link IRIxResolver} with the base URI which is resolved against the
    * current system default base.
    */
   public static Builder create(IRIx baseIRI) {
       return new Builder().base(baseIRI);
   }

   /**
    * Create a builder for a {@link IRIxResolver} with the base URI
    * which is resolved against the current system default base.
    */
   public static Builder create(String baseStr) {
       IRIx base = (baseStr == null) ? null : IRIs.resolveIRI(baseStr);
       return new Builder().base(base);
   }

   public static class Builder {
       // null is "unset".
       private Optional<IRIx> base   = null;
       private boolean resolve       = true;
       private boolean allowRelative = true;

       private Builder() {}

       public Builder base(IRIx baseURI) {
           this.base = Optional.ofNullable(baseURI);
           return this;
       }

       public Builder base(String baseStr) {
           IRIx baseIRI = (baseStr == null) ? null : IRIs.resolveIRI(baseStr);
           this.base = Optional.ofNullable(baseIRI);
           return this;
       }

       public Builder noBase() {
           this.base = Optional.empty();
           return this;
       }

       public Builder resolve(boolean resolveURIs) {
           this.resolve = resolveURIs;
           return this;
       }

       public Builder allowRelative(boolean allowRelative) {
           this.allowRelative = allowRelative;
           return this;
       }

       public IRIxResolver build() {
           if ( base == null )
               throw new IRIException("Base has not been set");
           IRIx baseIRI = base.orElse(null);
           return new IRIxResolver(baseIRI, resolve, allowRelative);
       }
   }
}

