import * as fs from 'fs';
import * as jsonc from "jsonc-parser";
import * as path from 'path';
import * as vscode from 'vscode';
import * as vscodelc from 'vscode-languageclient';
import * as vscodelct from 'vscode-languageserver-types';

// Parameters for the semantic highlighting (server-side) push notification.
// Mirrors the structure in the semantic highlighting proposal for LSP.
interface SemanticHighlightingParams {
  // The text document that has to be decorated with the semantic highlighting
  // information.
  textDocument: vscodelct.VersionedTextDocumentIdentifier;
  // An array of semantic highlighting information.
  lines: SemanticHighlightingInformation[];
}
// Contains the highlighting information for a specified line. Mirrors the
// structure in the semantic highlighting proposal for LSP.
interface SemanticHighlightingInformation {
  // The zero-based line position in the text document.
  line: number;
  // A base64 encoded string representing every single highlighted characters
  // with its start position, length and the "lookup table" index of of the
  // semantic highlighting Text Mate scopes.
  tokens?: string;
}

// A SemanticHighlightingToken decoded from the base64 data sent by clangd.
interface SemanticHighlightingToken {
  // Start column for this token.
  character: number;
  // Length of the token.
  length: number;
  // The TextMate scope index to the clangd scope lookup table.
  scopeIndex: number;
}
// A line of decoded highlightings from the data clangd sent.
export interface SemanticHighlightingLine {
  // The zero-based line position in the text document.
  line: number;
  // All SemanticHighlightingTokens on the line.
  tokens: SemanticHighlightingToken[];
}

// Language server push notification providing the semantic highlighting
// information for a text document.
export const NotificationType =
    new vscodelc.NotificationType<SemanticHighlightingParams, void>(
        'textDocument/semanticHighlighting');

// The feature that should be registered in the vscode lsp for enabling
// experimental semantic highlighting.
export class SemanticHighlightingFeature implements vscodelc.StaticFeature {
  // The TextMate scope lookup table. A token with scope index i has the scopes
  // on index i in the lookup table.
  scopeLookupTable: string[][];
  // The object that applies the highlightings clangd sends.
  highlighter: Highlighter;
  // Any disposables that should be cleaned up when clangd crashes.
  private subscriptions: vscode.Disposable[] = [];
  fillClientCapabilities(capabilities: vscodelc.ClientCapabilities) {
    // Extend the ClientCapabilities type and add semantic highlighting
    // capability to the object.
    const textDocumentCapabilities: vscodelc.TextDocumentClientCapabilities&
        {semanticHighlightingCapabilities?: {semanticHighlighting : boolean}} =
        capabilities.textDocument;
    textDocumentCapabilities.semanticHighlightingCapabilities = {
      semanticHighlighting : true,
    };
  }

  async loadCurrentTheme() {
    const themeRuleMatcher = new ThemeRuleMatcher(
        await loadTheme(vscode.workspace.getConfiguration('workbench')
                            .get<string>('colorTheme')));
    this.highlighter.initialize(themeRuleMatcher);
  }

  initialize(capabilities: vscodelc.ServerCapabilities,
             documentSelector: vscodelc.DocumentSelector|undefined) {
    // The semantic highlighting capability information is in the capabilities
    // object but to access the data we must first extend the ServerCapabilities
    // type.
    const serverCapabilities: vscodelc.ServerCapabilities&
        {semanticHighlighting?: {scopes : string[][]}} = capabilities;
    if (!serverCapabilities.semanticHighlighting)
      return;
    this.scopeLookupTable = serverCapabilities.semanticHighlighting.scopes;
    // Important that highlighter is created before the theme is loading as
    // otherwise it could try to update the themeRuleMatcher without the
    // highlighter being created.
    this.highlighter = new Highlighter(this.scopeLookupTable);
    this.subscriptions.push(vscode.Disposable.from(this.highlighter));
    // Adds a listener to reload the theme when it changes.
    this.subscriptions.push(
        vscode.workspace.onDidChangeConfiguration((conf) => {
          if (!conf.affectsConfiguration('workbench.colorTheme'))
            return;
          this.loadCurrentTheme();
        }));
    this.loadCurrentTheme();
    // Event handling for handling with TextDocuments/Editors lifetimes.
    this.subscriptions.push(vscode.window.onDidChangeVisibleTextEditors(
        (editors: vscode.TextEditor[]) =>
            editors.forEach((e) => this.highlighter.applyHighlights(
                                e.document.uri.toString()))));
    this.subscriptions.push(vscode.workspace.onDidCloseTextDocument(
        (doc) => this.highlighter.removeFileHighlightings(doc.uri.toString())));
  }

  handleNotification(params: SemanticHighlightingParams) {
    const lines: SemanticHighlightingLine[] = params.lines.map(
        (line) => ({line : line.line, tokens : decodeTokens(line.tokens)}));
    this.highlighter.highlight(params.textDocument.uri, lines);
  }
  // Disposes of all disposable resources used by this object.
  public dispose() {
    this.subscriptions.forEach((d) => d.dispose());
    this.subscriptions = [];
  }
}

// Converts a string of base64 encoded tokens into the corresponding array of
// HighlightingTokens.
export function decodeTokens(tokens: string): SemanticHighlightingToken[] {
  const scopeMask = 0xFFFF;
  const lenShift = 0x10;
  const uint32Size = 4;
  const buf = Buffer.from(tokens, 'base64');
  const retTokens = [];
  for (let i = 0, end = buf.length / uint32Size; i < end; i += 2) {
    const start = buf.readUInt32BE(i * uint32Size);
    const lenKind = buf.readUInt32BE((i + 1) * uint32Size);
    const scopeIndex = lenKind & scopeMask;
    const len = lenKind >>> lenShift;
    retTokens.push({character : start, scopeIndex : scopeIndex, length : len});
  }

  return retTokens;
}

// The main class responsible for processing of highlightings that clangd
// sends.
export class Highlighter {
  // Maps uris with currently open TextDocuments to the current highlightings.
  private files: Map<string, Map<number, SemanticHighlightingLine>> = new Map();
  // DecorationTypes for the current theme that are used when highlighting. A
  // SemanticHighlightingToken with scopeIndex i should have the decoration at
  // index i in this list.
  private decorationTypes: vscode.TextEditorDecorationType[] = [];
  // The clangd TextMate scope lookup table.
  private scopeLookupTable: string[][];
  constructor(scopeLookupTable: string[][]) {
    this.scopeLookupTable = scopeLookupTable;
  }
  public dispose() {
    this.files.clear();
    this.decorationTypes.forEach((t) => t.dispose());
    // Dispose must not be not called multiple times if initialize is
    // called again.
    this.decorationTypes = [];
  }
  // This function must be called at least once or no highlightings will be
  // done. Sets the theme that is used when highlighting. Also triggers a
  // recolorization for all current highlighters. Should be called whenever the
  // theme changes and has been loaded. Should also be called when the first
  // theme is loaded.
  public initialize(themeRuleMatcher: ThemeRuleMatcher) {
    this.decorationTypes.forEach((t) => t.dispose());
    this.decorationTypes = this.scopeLookupTable.map((scopes) => {
      const options: vscode.DecorationRenderOptions = {
        // If there exists no rule for this scope the matcher returns an empty
        // color. That's ok because vscode does not do anything when applying
        // empty decorations.
        color : themeRuleMatcher.getBestThemeRule(scopes[0]).foreground,
        // If the rangeBehavior is set to Open in any direction the
        // highlighting becomes weird in certain cases.
        rangeBehavior : vscode.DecorationRangeBehavior.ClosedClosed,
      };
      return vscode.window.createTextEditorDecorationType(options);
    });
    this.getVisibleTextEditorUris().forEach((fileUri) =>
                                                this.applyHighlights(fileUri));
  }

  // Adds incremental highlightings to the current highlightings for the file
  // with fileUri. Also applies the highlightings to any associated
  // TextEditor(s).
  public highlight(fileUri: string,
                   highlightingLines: SemanticHighlightingLine[]) {
    if (!this.files.has(fileUri)) {
      this.files.set(fileUri, new Map());
    }
    const fileHighlightings = this.files.get(fileUri);
    highlightingLines.forEach((line) => fileHighlightings.set(line.line, line));
    this.applyHighlights(fileUri);
  }

  // Applies all the highlightings currently stored for a file with fileUri.
  public applyHighlights(fileUri: string) {
    if (!this.files.has(fileUri))
      // There are no highlightings for this file, must return early or will get
      // out of bounds when applying the decorations below.
      return;
    if (!this.decorationTypes.length)
      // Can't apply any decorations when there is no theme loaded.
      return;
    // This must always do a full re-highlighting due to the fact that
    // TextEditorDecorationType are very expensive to create (which makes
    // incremental updates infeasible). For this reason one
    // TextEditorDecorationType is used per scope.
    const ranges = this.getDecorationRanges(fileUri);
    vscode.window.visibleTextEditors.forEach((e) => {
      if (e.document.uri.toString() !== fileUri)
        return;
      this.decorationTypes.forEach((d, i) => e.setDecorations(d, ranges[i]));
    });
  }

  // Called when a text document is closed. Removes any highlighting entries for
  // the text document that was closed.
  public removeFileHighlightings(fileUri: string) {
    // If there exists no entry the call to delete just returns false.
    this.files.delete(fileUri);
  }

  // Gets the uris as strings for the currently visible text editors.
  protected getVisibleTextEditorUris(): string[] {
    return vscode.window.visibleTextEditors.map((e) =>
                                                    e.document.uri.toString());
  }

  // Returns the ranges that should be used when decorating. Index i in the
  // range array has the decoration type at index i of this.decorationTypes.
  protected getDecorationRanges(fileUri: string): vscode.Range[][] {
    if (!this.files.has(fileUri))
      // this.files should always have an entry for fileUri if we are here. But
      // if there isn't one we don't want to crash the extension. This is also
      // useful for tests.
      return [];
    const lines: SemanticHighlightingLine[] =
        Array.from(this.files.get(fileUri).values());
    const decorations: vscode.Range[][] = this.decorationTypes.map(() => []);
    lines.forEach((line) => {
      line.tokens.forEach((token) => {
        decorations[token.scopeIndex].push(new vscode.Range(
            new vscode.Position(line.line, token.character),
            new vscode.Position(line.line, token.character + token.length)));
      });
    });
    return decorations;
  }
}

// A rule for how to color TextMate scopes.
interface TokenColorRule {
  // A TextMate scope that specifies the context of the token, e.g.
  // "entity.name.function.cpp".
  scope: string;
  // foreground is the color tokens of this scope should have.
  foreground: string;
}

export class ThemeRuleMatcher {
  // The rules for the theme.
  private themeRules: TokenColorRule[];
  // A cache for the getBestThemeRule function.
  private bestRuleCache: Map<string, TokenColorRule> = new Map();
  constructor(rules: TokenColorRule[]) { this.themeRules = rules; }
  // Returns the best rule for a scope.
  getBestThemeRule(scope: string): TokenColorRule {
    if (this.bestRuleCache.has(scope))
      return this.bestRuleCache.get(scope);
    let bestRule: TokenColorRule = {scope : '', foreground : ''};
    this.themeRules.forEach((rule) => {
      // The best rule for a scope is the rule that is the longest prefix of the
      // scope (unless a perfect match exists in which case the perfect match is
      // the best). If a rule is not a prefix and we tried to match with longest
      // common prefix instead variables would be highlighted as `less`
      // variables when using Light+ (as variable.other would be matched against
      // variable.other.less in this case). Doing common prefix matching also
      // means we could match variable.cpp to variable.css if variable.css
      // occurs before variable in themeRules.
      // FIXME: This is not defined in the TextMate standard (it is explicitly
      // undefined, https://macromates.com/manual/en/scope_selectors). Might
      // want to rank some other way.
      if (scope.startsWith(rule.scope) &&
          rule.scope.length > bestRule.scope.length)
        // This rule matches and is more specific than the old rule.
        bestRule = rule;
    });
    this.bestRuleCache.set(scope, bestRule);
    return bestRule;
  }
}

// Get all token color rules provided by the theme.
function loadTheme(themeName: string): Promise<TokenColorRule[]> {
  const extension =
      vscode.extensions.all.find((extension: vscode.Extension<any>) => {
        const contribs = extension.packageJSON.contributes;
        if (!contribs || !contribs.themes)
          return false;
        return contribs.themes.some((theme: any) => theme.id === themeName ||
                                                    theme.label === themeName);
      });

  if (!extension) {
    return Promise.reject('Could not find a theme with name: ' + themeName);
  }

  const themeInfo = extension.packageJSON.contributes.themes.find(
      (theme: any) => theme.id === themeName || theme.label === themeName);
  return parseThemeFile(path.join(extension.extensionPath, themeInfo.path));
}

/**
 * Parse the TextMate theme at fullPath. If there are multiple TextMate scopes
 * of the same name in the include chain only the earliest entry of the scope is
 * saved.
 * @param fullPath The absolute path to the theme.
 * @param seenScopes A set containing the name of the scopes that have already
 *     been set.
 */
export async function parseThemeFile(
    fullPath: string, seenScopes?: Set<string>): Promise<TokenColorRule[]> {
  if (!seenScopes)
    seenScopes = new Set();
  // FIXME: Add support for themes written as .tmTheme.
  if (path.extname(fullPath) === '.tmTheme')
    return [];
  try {
    const contents = await readFileText(fullPath);
    const parsed = jsonc.parse(contents);
    const rules: TokenColorRule[] = [];
    // To make sure it does not crash if tokenColors is undefined.
    if (!parsed.tokenColors)
      parsed.tokenColors = [];
    parsed.tokenColors.forEach((rule: any) => {
      if (!rule.scope || !rule.settings || !rule.settings.foreground)
        return;
      const textColor = rule.settings.foreground;
      // Scopes that were found further up the TextMate chain should not be
      // overwritten.
      const addColor = (scope: string) => {
        if (seenScopes.has(scope))
          return;
        rules.push({scope, foreground : textColor});
        seenScopes.add(scope);
      };
      if (rule.scope instanceof Array) {
        return rule.scope.forEach((s: string) => addColor(s));
      }
      addColor(rule.scope);
    });

    if (parsed.include)
      // Get all includes and merge into a flat list of parsed json.
      return [
        ...(await parseThemeFile(
            path.join(path.dirname(fullPath), parsed.include), seenScopes)),
        ...rules
      ];
    return rules;
  } catch (err) {
    // If there is an error opening a file, the TextMate files that were
    // correctly found and parsed further up the chain should be returned.
    // Otherwise there will be no highlightings at all.
    console.warn('Could not open file: ' + fullPath + ', error: ', err);
  }

  return [];
}

function readFileText(path: string): Promise<string> {
  return new Promise((resolve, reject) => {
    fs.readFile(path, 'utf8', (err, data) => {
      if (err) {
        return reject(err);
      }
      return resolve(data);
    });
  });
}
