export const matcherTypes = ['hostname', 'regex'] as const;
export const redirectTypes = ['hostname', 'regex', 'simple'] as const;

export type MatcherType = typeof matcherTypes[number];
export type RedirectType = typeof redirectTypes[number];

export function narrowMatcherType(value: string): value is MatcherType {
  return matcherTypes.includes(value as MatcherType);
}

export function narrowRedirectType(value: string): value is RedirectType {
  return redirectTypes.includes(value as RedirectType);
}

export type RedirectParameters = {
  enabled: boolean;
  id: number;
  matcherType: MatcherType;
  matcherValue: string;
  redirectType: RedirectType;
  redirectValue: string;
};

export abstract class Redirect {
  public static idString(id: number): string {
    return `redirect:${id}`;
  }

  constructor(public parameters: RedirectParameters) {}

  public idString(): string {
    return Redirect.idString(this.parameters.id);
  }

  public isMatch(url: URL): boolean {
    if (this.parameters.matcherType === 'hostname') {
      const hostname = url.hostname.startsWith('www.')
        ? url.hostname.slice(4)
        : url.hostname;
      return hostname === this.parameters.matcherValue;
    }

    if (this.parameters.matcherType === 'regex') {
      const regex = new RegExp(this.parameters.matcherValue, 'gi');
      return regex.test(url.href);
    }

    return false;
  }

  public abstract redirect(url: URL | string): URL | string;
}
