// Copyright (C) 2021 The Android Open Source Project
//
// Licensed 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.

// Execution context of object validator
interface ValidatorContext {
  // Path to the current value starting from the root. Object field names are
  // stored as is, array indices are wrapped to square brackets. Represented
  // as an array to avoid unnecessary string concatenation: parts are going to
  // be concatenated into a single string when reporting errors, which should
  // not happen on a happy path.
  // Example: ["config", "androidLogBuffers", "1"] when parsing object
  // accessible through expression `root.config.androidLogBuffers[1]`
  path: string[];

  // Paths from the root to extraneous keys in a validated object.
  extraKeys: string[];

  // Paths from the root to keys containing values of wrong type in validated
  // object.
  invalidKeys: string[];
}

// Validator accepting arbitrary data structure and returning a typed value.
// Can throw an error if a part of the value does not have a reasonable
// default.
export interface Validator<T> {
  validate(input: unknown, context: ValidatorContext): T;
}

// Helper function to flatten array of path chunks into a single string
// Example: ["config", "androidLogBuffers", "1"] is mapped to
// "config.androidLogBuffers[1]".
function renderPath(path: string[]): string {
  let result = '';
  for (let i = 0; i < path.length; i++) {
    if (i > 0 && !path[i].startsWith('[')) {
      result += '.';
    }
    result += path[i];
  }
  return result;
}

export class ValidationError extends Error {}

// Abstract class for validating simple values, such as strings and booleans.
// Allows to avoid repetition of most of the code related to validation of
// these.
abstract class PrimitiveValidator<T> implements Validator<T> {
  defaultValue: T;
  required: boolean;

  constructor(defaultValue: T, required: boolean) {
    this.defaultValue = defaultValue;
    this.required = required;
  }

  // Abstract method that checks whether passed input has correct type.
  abstract predicate(input: unknown): input is T;

  validate(input: unknown, context: ValidatorContext): T {
    if (this.predicate(input)) {
      return input;
    }
    if (this.required) {
      throw new ValidationError(renderPath(context.path));
    }
    if (input !== undefined) {
      // The value is defined, but does not conform to the expected type;
      // proceed with returning the default value but report the key.
      context.invalidKeys.push(renderPath(context.path));
    }
    return this.defaultValue;
  }
}

class OptionalValidator<T> implements Validator<T|undefined> {
  private inner: Validator<T>;

  constructor(inner: Validator<T>) {
    this.inner = inner;
  }

  validate(input: unknown, context: ValidatorContext): T|undefined {
    if (input === undefined) {
      return undefined;
    }
    try {
      return this.inner.validate(input, context);
    } catch (e) {
      if (e instanceof ValidationError) {
        context.invalidKeys.push(renderPath(context.path));
        return undefined;
      }
      throw e;
    }
  }
}

class StringValidator extends PrimitiveValidator<string> {
  predicate(input: unknown): input is string {
    return typeof input === 'string';
  }
}

class NumberValidator extends PrimitiveValidator<number> {
  predicate(input: unknown): input is number {
    return typeof input === 'number';
  }
}

class BooleanValidator extends PrimitiveValidator<boolean> {
  predicate(input: unknown): input is boolean {
    return typeof input === 'boolean';
  }
}

// Type-level function returning resulting type of a validator.
export type ValidatedType<T> = T extends Validator<infer S>? S : never;

// Type-level function traversing a record of validator and returning record
// with the same keys and valid types.
export type RecordValidatedType<T> = {
  [k in keyof T]: ValidatedType<T[k]>
};

// Combinator for validators: takes a record of validators, and returns a
// validator for a record where record's fields passed to validator with the
// same name.
//
// Generic parameter T is instantiated to type of record of validators, and
// should be provided implicitly by type inference due to verbosity of its
// instantiations.
class RecordValidator<T extends Record<string, Validator<unknown>>> implements
    Validator<RecordValidatedType<T>> {
  validators: T;

  constructor(validators: T) {
    this.validators = validators;
  }

  validate(input: unknown, context: ValidatorContext): RecordValidatedType<T> {
    // If value is missing or of incorrect type, empty record is still processed
    // in the loop below to initialize default fields of the nested object.
    let o: object = {};
    if (typeof input === 'object' && input !== null) {
      o = input;
    } else if (input !== undefined) {
      context.invalidKeys.push(renderPath(context.path));
    }

    const result: Partial<RecordValidatedType<T>> = {};
    // Separate declaration is required to avoid assigning `string` type to `k`.
    for (const k in this.validators) {
      if (this.validators.hasOwnProperty(k)) {
        context.path.push(k);
        const validator = this.validators[k];

        // Accessing value of `k` of `o` is safe because `undefined` values are
        // considered to indicate a missing value and handled appropriately by
        // every provided validator.
        const valid =
            validator.validate((o as Record<string, unknown>)[k], context);

        result[k] = valid as ValidatedType<T[string]>;
        context.path.pop();
      }
    }

    // Check if passed object has any extra keys to be reported as such.
    for (const key of Object.keys(o)) {
      if (!this.validators.hasOwnProperty(key)) {
        context.path.push(key);
        context.extraKeys.push(renderPath(context.path));
        context.path.pop();
      }
    }
    return result as RecordValidatedType<T>;
  }
}

// Validator checking whether a value is one of preset values. Used in order to
// provide easy validation for union of literal types.
class OneOfValidator<T> implements Validator<T> {
  validValues: readonly T[];
  defaultValue: T;

  constructor(validValues: readonly T[], defaultValue: T) {
    this.defaultValue = defaultValue;
    this.validValues = validValues;
  }

  validate(input: unknown, context: ValidatorContext): T {
    if (this.validValues.includes(input as T)) {
      return input as T;
    } else if (input !== undefined) {
      context.invalidKeys.push(renderPath(context.path));
    }
    return this.defaultValue;
  }
}

// Validator for an array of elements, applying the same element validator for
// each element of an array. Uses empty array as a default value.
class ArrayValidator<T> implements Validator<T[]> {
  elementValidator: Validator<T>;

  constructor(elementValidator: Validator<T>) {
    this.elementValidator = elementValidator;
  }

  validate(input: unknown, context: ValidatorContext): T[] {
    const result: T[] = [];
    if (Array.isArray(input)) {
      for (let i = 0; i < input.length; i++) {
        context.path.push(`[${i}]`);
        result.push(this.elementValidator.validate(input[i], context));
        context.path.pop();
      }
    } else if (input !== undefined) {
      context.invalidKeys.push(renderPath(context.path));
    }
    return result;
  }
}

// Wrapper container for validation result contaiting diagnostic information in
// addition to the resulting typed value.
export interface ValidationResult<T> {
  result: T;
  invalidKeys: string[];
  extraKeys: string[];
}

// Wrapper for running a validator initializing the context.
export function runValidator<T>(
    validator: Validator<T>, input: unknown): ValidationResult<T> {
  const context: ValidatorContext = {
    path: [],
    invalidKeys: [],
    extraKeys: [],
  };
  const result = validator.validate(input, context);
  return {
    result,
    invalidKeys: context.invalidKeys,
    extraKeys: context.extraKeys,
  };
}

// Shorthands for the validator classes above enabling concise notation.
export function str(defaultValue = ''): StringValidator {
  return new StringValidator(defaultValue, false);
}

export const requiredStr = new StringValidator('', true);

export const optStr = new OptionalValidator<string>(requiredStr);

export function num(defaultValue = 0): NumberValidator {
  return new NumberValidator(defaultValue, false);
}

export const requiredNum = new NumberValidator(0, true);

export const optNum = new OptionalValidator<number>(requiredNum);

export function bool(defaultValue = false): BooleanValidator {
  return new BooleanValidator(defaultValue, false);
}

export const requiredBool = new BooleanValidator(false, true);

export const optBool = new OptionalValidator<boolean>(requiredBool);


export function record<T extends Record<string, Validator<unknown>>>(
    validators: T): RecordValidator<T> {
  return new RecordValidator<T>(validators);
}

export function oneOf<T>(
    values: readonly T[], defaultValue: T): OneOfValidator<T> {
  return new OneOfValidator<T>(values, defaultValue);
}

export function arrayOf<T>(elementValidator: Validator<T>): ArrayValidator<T> {
  return new ArrayValidator<T>(elementValidator);
}
