/*
 * Copyright © 2018 Adobe Systems Incorporated.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Adobe Author(s): Michiharu Ariza
 */

#ifndef HB_OT_CFF2_TABLE_HH
#define HB_OT_CFF2_TABLE_HH

#include "hb-ot-cff-common-private.hh"
#include "hb-subset-cff2.hh"

namespace CFF {

/*
 * CFF2 -- Compact Font Format (CFF) Version 2
 * https://docs.microsoft.com/en-us/typography/opentype/spec/cff2
 */
#define HB_OT_TAG_cff2 HB_TAG('C','F','F','2')

typedef CFFIndex<HBUINT32>  CFF2Index;
template <typename Type> struct CFF2IndexOf : IndexOf<HBUINT32, Type> {};

typedef CFF2Index         CFF2CharStrings;
typedef FDArray<HBUINT32> CFF2FDArray;
typedef Subrs<HBUINT32>   CFF2Subrs;

typedef FDSelect3_4<HBUINT32, HBUINT16> FDSelect4;
typedef FDSelect3_4_Range<HBUINT32, HBUINT16> FDSelect4_Range;

struct CFF2FDSelect
{
  inline bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
  {
    TRACE_SANITIZE (this);

    return_trace (likely (c->check_struct (this) && (format == 0 || format == 3 || format == 4) &&
                          (format == 0)?
                          u.format0.sanitize (c, fdcount):
                            ((format == 3)?
                            u.format3.sanitize (c, fdcount):
                            u.format4.sanitize (c, fdcount))));
  }

  inline bool serialize (hb_serialize_context_t *c, const CFF2FDSelect &src, unsigned int num_glyphs)
  {
    TRACE_SERIALIZE (this);
    unsigned int size = src.get_size (num_glyphs);
    CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size);
    if (unlikely (dest == nullptr)) return_trace (false);
    memcpy (dest, &src, size);
    return_trace (true);
  }

  inline unsigned int calculate_serialized_size (unsigned int num_glyphs) const
  { return get_size (num_glyphs); }

  inline unsigned int get_size (unsigned int num_glyphs) const
  {
    unsigned int size = format.static_size;
    if (format == 0)
      size += u.format0.get_size (num_glyphs);
    else if (format == 3)
      size += u.format3.get_size ();
    else
      size += u.format4.get_size ();
    return size;
  }

  inline hb_codepoint_t get_fd (hb_codepoint_t glyph) const
  {
    if (this == &Null(CFF2FDSelect))
      return 0;
    if (format == 0)
      return u.format0.get_fd (glyph);
    else if (format == 3)
      return u.format3.get_fd (glyph);
    else
      return u.format4.get_fd (glyph);
  }

  HBUINT8       format;
  union {
    FDSelect0   format0;
    FDSelect3   format3;
    FDSelect4   format4;
  } u;

  DEFINE_SIZE_MIN (2);
};

struct CFF2VariationStore
{
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (likely (c->check_struct (this)) && varStore.sanitize (c));
  }

  inline bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore)
  {
    TRACE_SERIALIZE (this);
    unsigned int size_ = varStore->get_size ();
    CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_);
    if (unlikely (dest == nullptr)) return_trace (false);
    memcpy (dest, varStore, size_);
    return_trace (true);
  }

  inline unsigned int get_size (void) const { return HBUINT16::static_size + size; }

  HBUINT16        size;
  VariationStore  varStore;

  DEFINE_SIZE_MIN (2 + VariationStore::min_size);
};

struct CFF2TopDictValues : TopDictValues
{
  inline void init (void)
  {
    TopDictValues::init ();
    vstoreOffset = 0;
    FDSelectOffset = 0;
  }

  inline void fini (void)
  {
    TopDictValues::fini ();
  }

  inline unsigned int calculate_serialized_size (void) const
  {
    unsigned int size = 0;
    for (unsigned int i = 0; i < values.len; i++)
    {
      OpCode op = values[i].op;
      switch (op)
      {
        case OpCode_vstore:
        case OpCode_FDSelect:
          size += OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (op);
          break;
        default:
          size += TopDictValues::calculate_serialized_op_size (values[i]);
          break;
      }
    }
    return size;
  }

  unsigned int  vstoreOffset;
  unsigned int  FDSelectOffset;
};

struct CFF2TopDictOpSet : TopDictOpSet
{
  static inline bool process_op (OpCode op, InterpEnv& env, CFF2TopDictValues& dictval)
  {
    switch (op) {
      case OpCode_FontMatrix:
        {
          DictVal val;
          val.init ();
          dictval.pushVal (op, env.substr);
          env.argStack.clear ();
        }
        break;

      case OpCode_vstore:
        if (unlikely (!env.argStack.check_pop_uint (dictval.vstoreOffset)))
          return false;
        env.argStack.clear ();
        break;
      case OpCode_FDSelect:
        if (unlikely (!env.argStack.check_pop_uint (dictval.FDSelectOffset)))
          return false;
        env.argStack.clear ();
        break;
    
      default:
        if (unlikely (!TopDictOpSet::process_op (op, env, dictval)))
          return false;
        /* Record this operand below if stack is empty, otherwise done */
        if (!env.argStack.is_empty ()) return true;
    }

    dictval.pushVal (op, env.substr);
    return true;
  }
};

struct CFF2FontDictValues : DictValues<OpStr>
{
  inline void init (void)
  {
    DictValues<OpStr>::init ();
    privateDictInfo.init ();
  }

  inline void fini (void)
  {
    DictValues<OpStr>::fini ();
  }

  TableInfo    privateDictInfo;
};

struct CFF2FontDictOpSet : DictOpSet
{
  static inline bool process_op (OpCode op, InterpEnv& env, CFF2FontDictValues& dictval)
  {
    switch (op) {
      case OpCode_Private:
        if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.offset)))
          return false;
        if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
          return false;
        env.argStack.clear ();
        break;
    
      default:
        if (unlikely (!DictOpSet::process_op (op, env)))
          return false;
        if (!env.argStack.is_empty ())
          return true;
    }

    dictval.pushVal (op, env.substr);
    return true;
  }
};

template <typename VAL>
struct CFF2PrivateDictValues_Base : DictValues<VAL>
{
  inline void init (void)
  {
    DictValues<VAL>::init ();
    subrsOffset = 0;
    localSubrs = &Null(CFF2Subrs);
  }

  inline void fini (void)
  {
    DictValues<VAL>::fini ();
  }

  inline unsigned int calculate_serialized_size (void) const
  {
    unsigned int size = 0;
    for (unsigned int i = 0; i < DictValues<VAL>::values.len; i++)
      if (DictValues<VAL>::values[i].op == OpCode_Subrs)
        size += OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Subrs);
      else
        size += DictValues<VAL>::values[i].str.len;
    return size;
  }

  unsigned int      subrsOffset;
  const CFF2Subrs   *localSubrs;
};

typedef CFF2PrivateDictValues_Base<OpStr> CFF2PrivateDictValues_Subset;
typedef CFF2PrivateDictValues_Base<DictVal> CFF2PrivateDictValues;

struct CFF2PrivateDictOpSet : DictOpSet
{
  static inline bool process_op (OpCode op, InterpEnv& env, CFF2PrivateDictValues& dictval)
  {
    DictVal val;
    val.init ();

    switch (op) {
      case OpCode_StdHW:
      case OpCode_StdVW:
      case OpCode_BlueScale:
      case OpCode_BlueShift:
      case OpCode_BlueFuzz:
      case OpCode_ExpansionFactor:
      case OpCode_LanguageGroup:
        if (unlikely (!env.argStack.check_pop_num (val.single_val)))
          return false;
        env.argStack.clear ();
        break;
      case OpCode_BlueValues:
      case OpCode_OtherBlues:
      case OpCode_FamilyBlues:
      case OpCode_FamilyOtherBlues:
      case OpCode_StemSnapH:
      case OpCode_StemSnapV:
        if (unlikely (!env.argStack.check_pop_delta (val.multi_val)))
          return false;
        env.argStack.clear ();
        break;
      case OpCode_Subrs:
        if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
          return false;
        env.argStack.clear ();
        break;
      case OpCode_vsindexdict:
      case OpCode_blenddict:
        // XXX: TODO
        return true;

      default:
        if (unlikely (!DictOpSet::process_op (op, env)))
          return false;
        if (!env.argStack.is_empty ()) return true;
        break;
    }

    dictval.pushVal (op, env.substr, val);
    return true;
  }
};

struct CFF2PrivateDictOpSet_Subset : DictOpSet
{
  static inline bool process_op (OpCode op, InterpEnv& env, CFF2PrivateDictValues_Subset& dictval)
  {
    switch (op) {
      case OpCode_BlueValues:
      case OpCode_OtherBlues:
      case OpCode_FamilyBlues:
      case OpCode_FamilyOtherBlues:
      case OpCode_StdHW:
      case OpCode_StdVW:
      case OpCode_BlueScale:
      case OpCode_BlueShift:
      case OpCode_BlueFuzz:
      case OpCode_StemSnapH:
      case OpCode_StemSnapV:
      case OpCode_LanguageGroup:
      case OpCode_ExpansionFactor:
        env.argStack.clear ();
        break;

      case OpCode_blenddict:
        env.argStack.clear ();
        return true;

      case OpCode_Subrs:
        if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
          return false;
        env.argStack.clear ();
        break;

      default:
        if (unlikely (!DictOpSet::process_op (op, env)))
          return false;
        if (!env.argStack.is_empty ()) return true;
        break;
    }

    dictval.pushVal (op, env.substr);
    return true;
  }
};

typedef DictInterpreter<CFF2TopDictOpSet, CFF2TopDictValues> CFF2TopDict_Interpreter;
typedef DictInterpreter<CFF2FontDictOpSet, CFF2FontDictValues> CFF2FontDict_Interpreter;
typedef DictInterpreter<CFF2PrivateDictOpSet, CFF2PrivateDictValues> CFF2PrivateDict_Interpreter;

}; /* namespace CFF */

namespace OT {

using namespace CFF;

struct cff2
{
  static const hb_tag_t tableTag        = HB_OT_TAG_cff2;

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
                  likely (version.major == 2));
  }

  template <typename PrivOpSet, typename PrivDictVal>
  struct accelerator_templ_t
  {
    inline void init (hb_face_t *face)
    {
      topDict.init ();
      fontDicts.init ();
      privateDicts.init ();
      
      this->blob = sc.reference_table<cff2> (face);

      /* setup for run-time santization */
      sc.init (this->blob);
      sc.start_processing ();
      
      const OT::cff2 *cff2 = this->blob->template as<OT::cff2> ();

      if (cff2 == &Null(OT::cff2))
      { fini (); return; }

      { /* parse top dict */
        ByteStr topDictStr (cff2 + cff2->topDict, cff2->topDictSize);
        if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
        CFF2TopDict_Interpreter top_interp;
        top_interp.env.init (topDictStr);
        if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
      }
      
      globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize);
      varStore = &StructAtOffsetOrNull<CFF2VariationStore> (cff2, topDict.vstoreOffset);
      charStrings = &StructAtOffsetOrNull<CFF2CharStrings> (cff2, topDict.charStringsOffset);
      fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset);
      fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset);
      
      if (((varStore != &Null(CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) ||
          (charStrings == &Null(CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) ||
          (fdArray == &Null(CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) ||
          (((fdSelect != &Null(CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count)))))
      { fini (); return; }

      num_glyphs = charStrings->count;
      if (num_glyphs != sc.get_num_glyphs ())
      { fini (); return; }

      fdCount = fdArray->count;
      privateDicts.resize (fdCount);

      /* parse font dicts and gather private dicts */
      for (unsigned int i = 0; i < fdCount; i++)
      {
        const ByteStr fontDictStr = (*fdArray)[i];
        if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
        CFF2FontDictValues  *font;
        CFF2FontDict_Interpreter font_interp;
        font_interp.env.init (fontDictStr);
        font = fontDicts.push ();
        if (unlikely (!font_interp.interpret (*font))) { fini (); return; }

        const ByteStr privDictStr (StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset), font->privateDictInfo.size);
        if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
        DictInterpreter<PrivOpSet, PrivDictVal> priv_interp;
        priv_interp.env.init(privDictStr);
        if (unlikely (!priv_interp.interpret (privateDicts[i]))) { fini (); return; }

        privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (privDictStr.str, privateDicts[i].subrsOffset);
        if (privateDicts[i].localSubrs != &Null(CFF2Subrs) &&
          unlikely (!privateDicts[i].localSubrs->sanitize (&sc)))
        { fini (); return; }
      }
    }

    inline void fini (void)
    {
      sc.end_processing ();
      fontDicts.fini ();
      privateDicts.fini ();
      hb_blob_destroy (blob);
      blob = nullptr;
    }

    inline bool is_valid (void) const { return blob != nullptr; }

    inline bool get_extents (hb_codepoint_t glyph,
           hb_glyph_extents_t *extents) const
    {
      // XXX: TODO
      if (glyph >= num_glyphs)
        return false;
      
      return true;
    }

    protected:
    hb_blob_t               *blob;
    hb_sanitize_context_t   sc;

    public:
    CFF2TopDictValues         topDict;
    const CFF2Subrs           *globalSubrs;
    const CFF2VariationStore  *varStore;
    const CFF2CharStrings     *charStrings;
    const CFF2FDArray         *fdArray;
    const CFF2FDSelect        *fdSelect;
    unsigned int              fdCount;

    hb_vector_t<CFF2FontDictValues>     fontDicts;
    hb_vector_t<PrivDictVal>  privateDicts;

    unsigned int            num_glyphs;
  };

  typedef accelerator_templ_t<CFF2PrivateDictOpSet, CFF2PrivateDictValues> accelerator_t;
  typedef accelerator_templ_t<CFF2PrivateDictOpSet_Subset, CFF2PrivateDictValues_Subset> accelerator_subset_t;

  inline bool subset (hb_subset_plan_t *plan) const
  {
    hb_blob_t *cff2_prime = nullptr;

    bool success = true;
    if (hb_subset_cff2 (plan, &cff2_prime)) {
      success = success && plan->add_table (HB_OT_TAG_cff2, cff2_prime);
    } else {
      success = false;
    }
    hb_blob_destroy (cff2_prime);

    return success;
  }

  public:
  FixedVersion<HBUINT8> version;        /* Version of CFF2 table. set to 0x0200u */
  OffsetTo<TopDict, HBUINT8> topDict;   /* headerSize = Offset to Top DICT. */
  HBUINT16       topDictSize;           /* Top DICT size */

  public:
  DEFINE_SIZE_STATIC (5);
};

} /* namespace OT */

#endif /* HB_OT_CFF2_TABLE_HH */
