const db = require('./db/models');
const {
  RESERVED_SUBDOMAINS,
  normalizeSubdomain,
  validateSubdomainOrThrow,
  getRequestHostname,
  extractTenantSubdomain,
} = require('./tenantSubdomain');

function badRequest(message) {
  const error = new Error(message);
  error.code = 400;
  throw error;
}

async function resolveTenantContextByHost(reqOrHost, options = {}) {
  const transaction = options.transaction;
  const required = options.required ?? false;
  const hostname = getRequestHostname(reqOrHost);
  const subdomain = extractTenantSubdomain(hostname);

  if (!subdomain) {
    if (required) {
      badRequest('A valid tenant subdomain is required for this request.');
    }

    return {
      subdomain: null,
      tenant: null,
      organization: null,
    };
  }

  const tenant = await db.tenants.findOne({
    where: { subdomain },
    include: [
      {
        model: db.organizations,
        as: 'organizations',
      },
    ],
    transaction,
  });

  if (!tenant) {
    badRequest(`No tenant is configured for subdomain '${subdomain}'.`);
  }

  if (!tenant.organizations) {
    badRequest(`Tenant '${subdomain}' is not linked to an organization.`);
  }

  return {
    subdomain,
    tenant,
    organization: tenant.organizations,
  };
}

module.exports = {
  RESERVED_SUBDOMAINS,
  normalizeSubdomain,
  validateSubdomainOrThrow,
  extractTenantSubdomain,
  resolveTenantContextByHost,
};
