﻿using Lucene.Net.Analysis.Ja.Dict;
using Lucene.Net.Codecs;
using Lucene.Net.Store;
using Lucene.Net.Support;
using System;
using System.IO;

namespace Lucene.Net.Analysis.Ja.Util
{
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You 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.
     */

    public sealed class CharacterDefinitionWriter
    {
        private readonly byte[] characterCategoryMap = new byte[0x10000];

        private readonly bool[] invokeMap = new bool[CharacterDefinition.CLASS_COUNT];
        private readonly bool[] groupMap = new bool[CharacterDefinition.CLASS_COUNT];

        /// <summary>
        /// Constructor for building. TODO: remove write access
        /// </summary>
        public CharacterDefinitionWriter()
        {
            Arrays.Fill(characterCategoryMap, CharacterDefinition.DEFAULT);
        }

        /// <summary>
        /// Put mapping from unicode code point to character class.
        /// </summary>
        /// <param name="codePoint">Code point.</param>
        /// <param name="characterClassName">Character class name.</param>
        public void PutCharacterCategory(int codePoint, string characterClassName)
        {
            characterClassName = characterClassName.Split(' ')[0]; // use first
                                                                    // category
                                                                    // class

            // Override Nakaguro
            if (codePoint == 0x30FB)
            {
                characterClassName = "SYMBOL";
            }
            characterCategoryMap[codePoint] = CharacterDefinition.LookupCharacterClass(characterClassName);
        }

        public void PutInvokeDefinition(string characterClassName, int invoke, int group, int length)
        {
            byte characterClass = CharacterDefinition.LookupCharacterClass(characterClassName);
            invokeMap[characterClass] = invoke == 1;
            groupMap[characterClass] = group == 1;
            // TODO: length def ignored
        }

        public void Write(string baseDir)
        {
            //string filename = baseDir + System.IO.Path.DirectorySeparatorChar +
            //    typeof(CharacterDefinition).FullName.Replace('.', System.IO.Path.DirectorySeparatorChar) + CharacterDefinition.FILENAME_SUFFIX;

            // LUCENENET specific: we don't need to do a "classpath" output directory, since we
            // are changing the implementation to read files dynamically instead of making the
            // user recompile with the new files.
            string filename = System.IO.Path.Combine(baseDir, typeof(CharacterDefinition).Name + CharacterDefinition.FILENAME_SUFFIX);
            //new File(filename).getParentFile().mkdirs();
            System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(baseDir));
            using (Stream os = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                DataOutput @out = new OutputStreamDataOutput(os);
                CodecUtil.WriteHeader(@out, CharacterDefinition.HEADER, CharacterDefinition.VERSION);
                @out.WriteBytes(characterCategoryMap, 0, characterCategoryMap.Length);
                for (int i = 0; i < CharacterDefinition.CLASS_COUNT; i++)
                {
                    byte b = (byte)(
                      (invokeMap[i] ? 0x01 : 0x00) |
                      (groupMap[i] ? 0x02 : 0x00)
                    );
                    @out.WriteByte(b);
                }
            }
        }
    }
}
