// fst_test.cc

// 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.
//
// Copyright 2005-2010 Google, Inc.
// Author: riley@google.com (Michael Riley)
//
// \file
// Regression test for FST classes.

#include "./fst_test.h"

#include <fst/compact-fst.h>
#include <fst/const-fst.h>
#include <fst/edit-fst.h>
#include <fst/matcher-fst.h>


namespace fst {

// A user-defined arc type.
struct CustomArc {
  typedef short Label;
  typedef ProductWeight<TropicalWeight, LogWeight> Weight;
  typedef int64 StateId;

  CustomArc(Label i, Label o, Weight w, StateId s) :
    ilabel(i), olabel(o), weight(w), nextstate(s) {}
  CustomArc() {}

  static const string &Type() {  // Arc type name
    static const string type = "my";
    return type;
  }

  Label ilabel;       // Transition input label
  Label olabel;       // Transition output label
  Weight weight;      // Transition weight
  StateId nextstate;  // Transition destination state
};


// A user-defined compactor for test FST.
template <class A>
class CustomCompactor {
 public:
  typedef A Arc;
  typedef typename A::Label Label;
  typedef typename A::StateId StateId;
  typedef typename A::Weight Weight;
  typedef pair<Label, Weight> Element;

  Element Compact(StateId s, const A &arc) const {
    return make_pair(arc.ilabel, arc.weight);
  }

  Arc Expand(StateId s, const Element &p, uint32 f = kArcValueFlags) const {
    return p.first == kNoLabel ?
        Arc(kNoLabel, kNoLabel, p.second, kNoStateId) :
        Arc(p.first, 0, p.second, s);
  }

  ssize_t Size() const { return -1;}

  uint64 Properties() const { return 0ULL;}

  bool Compatible(const Fst<A> &fst) const {
    return true;
  }

  static const string &Type() {
    static const string type = "my";
    return type;
  }

  bool Write(ostream &strm) const { return true; }

  static CustomCompactor *Read(istream &strm) {
    return new CustomCompactor;
  }
};


REGISTER_FST(VectorFst, CustomArc);
REGISTER_FST(ConstFst, CustomArc);
static fst::FstRegisterer<
  CompactFst<StdArc, CustomCompactor<StdArc> > >
CompactFst_StdArc_CustomCompactor_registerer;
static fst::FstRegisterer<
  CompactFst<CustomArc, CustomCompactor<CustomArc> > >
CompactFst_CustomArc_CustomCompactor_registerer;
static fst::FstRegisterer<ConstFst<StdArc, uint16> >
ConstFst_StdArc_uint16_registerer;
static fst::FstRegisterer<
  CompactFst<StdArc, CustomCompactor<StdArc>, uint16> >
CompactFst_StdArc_CustomCompactor_uint16_registerer;

}  // namespace fst


using fst::FstTester;
using fst::VectorFst;
using fst::ConstFst;
using fst::MatcherFst;
using fst::CompactFst;
using fst::Fst;
using fst::StdArc;
using fst::CustomArc;
using fst::CustomCompactor;
using fst::StdArcLookAheadFst;
using fst::EditFst;

int main(int argc, char **argv) {
  FLAGS_fst_verify_properties = true;
  std::set_new_handler(FailedNewHandler);
  SetFlags(argv[0], &argc, &argv, true);

  // VectorFst<StdArc> tests
  {
    FstTester< VectorFst<StdArc> > std_vector_tester;
    std_vector_tester.TestBase();
    std_vector_tester.TestExpanded();
    std_vector_tester.TestAssign();
    std_vector_tester.TestCopy();
    std_vector_tester.TestIO();
    std_vector_tester.TestMutable();
  }

  // ConstFst<StdArc> tests
  {
    FstTester< ConstFst<StdArc> > std_const_tester;
    std_const_tester.TestBase();
    std_const_tester.TestExpanded();
    std_const_tester.TestCopy();
    std_const_tester.TestIO();
  }

  // CompactFst<StdArc, CustomCompactor<StdArc> >
  {
    FstTester< CompactFst<StdArc, CustomCompactor<StdArc> > >
        std_compact_tester;
    std_compact_tester.TestBase();
    std_compact_tester.TestExpanded();
    std_compact_tester.TestCopy();
    std_compact_tester.TestIO();
  }

  // VectorFst<CustomArc> tests
  {
    FstTester< VectorFst<CustomArc> > std_vector_tester;
    std_vector_tester.TestBase();
    std_vector_tester.TestExpanded();
    std_vector_tester.TestAssign();
    std_vector_tester.TestCopy();
    std_vector_tester.TestIO();
    std_vector_tester.TestMutable();
  }

  // ConstFst<CustomArc> tests
  {
    FstTester< ConstFst<CustomArc> > std_const_tester;
    std_const_tester.TestBase();
    std_const_tester.TestExpanded();
    std_const_tester.TestCopy();
    std_const_tester.TestIO();
  }

  // CompactFst<CustomArc, CustomCompactor<CustomArc> >
  {
    FstTester< CompactFst<CustomArc, CustomCompactor<CustomArc> > >
        std_compact_tester;
    std_compact_tester.TestBase();
    std_compact_tester.TestExpanded();
    std_compact_tester.TestCopy();
    std_compact_tester.TestIO();
  }

  // ConstFst<StdArc, uint16> tests
  {
    FstTester< ConstFst<StdArc, uint16> > std_const_tester;
    std_const_tester.TestBase();
    std_const_tester.TestExpanded();
    std_const_tester.TestCopy();
    std_const_tester.TestIO();
  }

  // CompactFst<StdArc, CustomCompactor<StdArc>, uint16>
  {
    FstTester< CompactFst<StdArc, CustomCompactor<StdArc>, uint16> >
        std_compact_tester;
    std_compact_tester.TestBase();
    std_compact_tester.TestExpanded();
    std_compact_tester.TestCopy();
    std_compact_tester.TestIO();
  }

  // FstTester<StdArcLookAheadFst>
  {
    FstTester<StdArcLookAheadFst> std_matcher_tester;
    std_matcher_tester.TestBase();
    std_matcher_tester.TestExpanded();
    std_matcher_tester.TestCopy();
  }

  // EditFst<StdArc> tests
  {
    FstTester< EditFst<StdArc> > std_edit_tester;
    std_edit_tester.TestBase();
    std_edit_tester.TestExpanded();
    std_edit_tester.TestAssign();
    std_edit_tester.TestCopy();
    std_edit_tester.TestMutable();
  }

  cout << "PASS" << endl;

  return 0;
}
