'use strict';

function findRelation_upToPath(urlObj, siteUrlObj, options) {
  // Path- or root-relative URL
  var pathOnly = urlObj.extra.hrefInfo.minimumPathOnly;

  // Matching scheme, scheme-relative or path-only
  var minimumScheme = urlObj.scheme === siteUrlObj.scheme || !urlObj.scheme;

  // Matching auth, ignoring auth or path-only
  var minimumAuth =
    minimumScheme &&
    (urlObj.auth === siteUrlObj.auth || options.removeAuth || pathOnly);

  // Matching host or path-only
  var www = options.ignore_www ? 'stripped' : 'full';
  var minimumHost =
    minimumAuth && (urlObj.host[www] === siteUrlObj.host[www] || pathOnly);

  // Matching port or path-only
  var minimumPort =
    minimumHost && (urlObj.port === siteUrlObj.port || pathOnly);

  urlObj.extra.relation.minimumScheme = minimumScheme;
  urlObj.extra.relation.minimumAuth = minimumAuth;
  urlObj.extra.relation.minimumHost = minimumHost;
  urlObj.extra.relation.minimumPort = minimumPort;

  urlObj.extra.relation.maximumScheme =
    !minimumScheme || (minimumScheme && !minimumAuth);
  urlObj.extra.relation.maximumAuth =
    !minimumScheme || (minimumScheme && !minimumHost);
  urlObj.extra.relation.maximumHost =
    !minimumScheme || (minimumScheme && !minimumPort);
}

function findRelation_pathOn(urlObj, siteUrlObj, options) {
  var queryOnly = urlObj.extra.hrefInfo.minimumQueryOnly;
  var hashOnly = urlObj.extra.hrefInfo.minimumHashOnly;
  var empty = urlObj.extra.hrefInfo.empty; // not required, but self-documenting

  // From upToPath()
  var minimumPort = urlObj.extra.relation.minimumPort;
  var minimumScheme = urlObj.extra.relation.minimumScheme;

  // Matching port and path
  var minimumPath =
    minimumPort &&
    urlObj.path.absolute.string === siteUrlObj.path.absolute.string;

  // Matching resource or query/hash-only or empty
  var matchingResource =
    urlObj.resource === siteUrlObj.resource ||
    (!urlObj.resource && siteUrlObj.extra.resourceIsIndex) ||
    (options.removeDirectoryIndexes &&
      urlObj.extra.resourceIsIndex &&
      !siteUrlObj.resource);
  var minimumResource =
    minimumPath && (matchingResource || queryOnly || hashOnly || empty);

  // Matching query or hash-only/empty
  var query = options.removeEmptyQueries ? 'stripped' : 'full';
  var urlQuery = urlObj.query.string[query];
  var siteUrlQuery = siteUrlObj.query.string[query];
  var minimumQuery =
    (minimumResource && !!urlQuery && urlQuery === siteUrlQuery) ||
    ((hashOnly || empty) && !urlObj.extra.hrefInfo.separatorOnlyQuery);

  var minimumHash = minimumQuery && urlObj.hash === siteUrlObj.hash;

  urlObj.extra.relation.minimumPath = minimumPath;
  urlObj.extra.relation.minimumResource = minimumResource;
  urlObj.extra.relation.minimumQuery = minimumQuery;
  urlObj.extra.relation.minimumHash = minimumHash;

  urlObj.extra.relation.maximumPort =
    !minimumScheme || (minimumScheme && !minimumPath);
  urlObj.extra.relation.maximumPath =
    !minimumScheme || (minimumScheme && !minimumResource);
  urlObj.extra.relation.maximumResource =
    !minimumScheme || (minimumScheme && !minimumQuery);
  urlObj.extra.relation.maximumQuery =
    !minimumScheme || (minimumScheme && !minimumHash);
  urlObj.extra.relation.maximumHash =
    !minimumScheme || (minimumScheme && !minimumHash); // there's nothing after hash, so it's the same as maximumQuery

  // Matching path and/or resource with existing but non-matching site query
  urlObj.extra.relation.overridesQuery =
    minimumPath &&
    urlObj.extra.relation.maximumResource &&
    !minimumQuery &&
    !!siteUrlQuery;
}

module.exports = {
  pathOn: findRelation_pathOn,
  upToPath: findRelation_upToPath,
};