// Copyright (C) 2009 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.

package com.google.gwtexpui.safehtml.client;

import java.util.ArrayList;
import java.util.HashMap;

/** Lightweight map of names/values for element attribute construction. */
class AttMap {
  private static final Tag ANY = new AnyTag();
  private static final HashMap<String, Tag> TAGS;
  static {
    final Tag src = new SrcTag();
    TAGS = new HashMap<>();
    TAGS.put("a", new AnchorTag());
    TAGS.put("form", new FormTag());
    TAGS.put("img", src);
    TAGS.put("script", src);
    TAGS.put("frame", src);
  }

  private final ArrayList<String> names = new ArrayList<>();
  private final ArrayList<String> values = new ArrayList<>();

  private Tag tag = ANY;
  private int live;

  void reset(final String tagName) {
    tag = TAGS.get(tagName.toLowerCase());
    if (tag == null) {
      tag = ANY;
    }
    live = 0;
  }

  void onto(final Buffer raw, final SafeHtmlBuilder esc) {
    for (int i = 0; i < live; i++) {
      final String v = values.get(i);
      if (v.length() > 0) {
        raw.append(" ");
        raw.append(names.get(i));
        raw.append("=\"");
        esc.append(v);
        raw.append("\"");
      }
    }
  }

  String get(String name) {
    name = name.toLowerCase();

    for (int i = 0; i < live; i++) {
      if (name.equals(names.get(i))) {
        return values.get(i);
      }
    }
    return "";
  }

  void set(String name, final String value) {
    name = name.toLowerCase();
    tag.assertSafe(name, value);

    for (int i = 0; i < live; i++) {
      if (name.equals(names.get(i))) {
        values.set(i, value);
        return;
      }
    }

    final int i = live++;
    if (names.size() < live) {
      names.add(name);
      values.add(value);
    } else {
      names.set(i, name);
      values.set(i, value);
    }
  }

  private static void assertNotJavascriptUrl(final String value) {
    if (value.startsWith("#")) {
      // common in GWT, and safe, so bypass further checks

    } else if (value.trim().toLowerCase().startsWith("javascript:")) {
      // possibly unsafe, we could have random user code here
      // we can't tell if its safe or not so we refuse to accept
      //
      throw new RuntimeException("javascript unsafe in href: " + value);
    }
  }

  private static interface Tag {
    void assertSafe(String name, String value);
  }

  private static class AnyTag implements Tag {
    @Override
    public void assertSafe(String name, String value) {
    }
  }

  private static class AnchorTag implements Tag {
    @Override
    public void assertSafe(String name, String value) {
      if ("href".equals(name)) {
        assertNotJavascriptUrl(value);
      }
    }
  }

  private static class FormTag implements Tag {
    @Override
    public void assertSafe(String name, String value) {
      if ("action".equals(name)) {
        assertNotJavascriptUrl(value);
      }
    }
  }

  private static class SrcTag implements Tag {
    @Override
    public void assertSafe(String name, String value) {
      if ("src".equals(name)) {
        assertNotJavascriptUrl(value);
      }
    }
  }
}
