/**
 * 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.
 */
package org.apache.hadoop.hdfs.server.namenode;

import com.google.protobuf.ByteString;
import org.apache.hadoop.fs.Options;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.protocol.Block;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

import static org.apache.hadoop.hdfs.server.namenode.INodeId.INVALID_INODE_ID;

class RWTransaction extends Transaction {
  private static final long DELETED_INODE_ID = INVALID_INODE_ID;
  private static final ByteString DELETED_INODE = ByteString.EMPTY;

  private HashMap<Long, DB.INodeContainer> inodeMap = new HashMap<>();

  RWTransaction(FSDirectory fsd) {
    super(fsd);
  }

  RWTransaction begin() {
    fsd.writeLock();
    return this;
  }

  @Override
  FlatINode getINode(long id) {
    DB.INodeContainer c = inodeMap.get(id);
    if (c == null) {
      return getINodeFromDB(id);
    }
    return c.inode() == DELETED_INODE ? null : FlatINode.wrap(c.inode());
  }

  @Override
  long getChild(long parentId, ByteBuffer localName) {
    DB.INodeContainer c = inodeMap.get(parentId);
    if (c == null || c.children() == null) {
      return getChildFromDB(parentId, localName);
    }
    Long id = c.children().get(localName);
    return id == null || id == DELETED_INODE_ID ? INVALID_INODE_ID : id;
  }

  @Override
  DBChildrenView childrenView(long parent) {
    // TODO: This function only provides a read-only view for the content in
    // the DB. It needs to consider the modification in this transaction to
    // implement transactional semantic.
    DB.INodeContainer c = fsd.db().getINode(parent);
    return new MemDBChildrenView(c.readOnlyChildren());
  }

  @Override
  public void close() throws IOException {
    fsd.writeUnlock();
  }

  void putINode(long id, ByteString inode) {
    DB.INodeContainer c = ensureContainer(id);
    c.inode(inode);
  }

  void putChild(long parentId, ByteBuffer localName, long id) {
    DB.INodeContainer c = ensureContainer(parentId);
    ByteString s = ByteString.copyFrom(localName);
    c.ensureChildrenList().put(s.asReadOnlyByteBuffer(), id);
  }

  void deleteINode(long inodeId) {
    putINode(inodeId, DELETED_INODE);
  }

  void deleteChild(long parentId, ByteBuffer localName) {
    putChild(parentId, localName, DELETED_INODE_ID);
  }

  long allocateNewInodeId() {
    return fsd.allocateNewInodeId();
  }

  int getStringId(String str) {
    return fsd.ugid().getId(str);
  }

  private DB.INodeContainer ensureContainer(long inodeId) {
    DB.INodeContainer c = inodeMap.get(inodeId);
    if (c == null) {
      c = new DB.INodeContainer();
      inodeMap.put(inodeId, c);
    }
    return c;
  }

  void commit() {
    for (Map.Entry<Long, DB.INodeContainer> e : inodeMap.entrySet()) {
      long id = e.getKey();
      DB.INodeContainer c = e.getValue();
      if (c.inode() == DELETED_INODE) {
        fsd.db().inodeMap().remove(id);
        continue;
      }

      DB.INodeContainer dbContainer = fsd.db().ensureContainer(id);
      if (c.inode() != null) {
        dbContainer.inode(c.inode());
      }

      if (c.children() == null) {
        continue;
      }

      for (Map.Entry<ByteBuffer, Long> e1 : c.children().entrySet()) {
        ByteBuffer childName = e1.getKey();
        long childId = e1.getValue();
        if (e1.getValue() == INVALID_INODE_ID) {
          if (dbContainer.children() != null) {
            dbContainer.children().remove(childName);
          }
        } else {
          dbContainer.ensureChildrenList().put(childName, childId);
        }
      }
    }
    inodeMap.clear();
  }

  public void logMkDir(FlatINodesInPath iip) {
    fsd.getEditLog().logMkDir(iip, fsd.ugid());
  }

  public void logRename(
      String src, String dst, long mtime, boolean logRetryCache,
      Options.Rename[] options) {
    fsd.getEditLog().logRename(src, dst, mtime, logRetryCache, options);
  }

  public void logOpenFile(StringMap ugid, String src, FlatINode inode,
      boolean overwrite, boolean logRetryCache) {
    fsd.getEditLog().logOpenFile(ugid, src, inode, overwrite, logRetryCache);
  }

  public void logAddBlock(String src, FlatINodeFileFeature file) {
    fsd.getEditLog().logAddBlock(src, file);
  }

  public void logCloseFile(String path, FlatINode inode) {
    fsd.getEditLog().logCloseFile(fsd.ugid(), path, inode);
  }

  public void logSetPermissions(String src, FsPermission permission) {
    fsd.getEditLog().logSetPermissions(src, permission);
  }

  public void logTimes(String src, long mtime, long atime) {
    fsd.getEditLog().logTimes(src, mtime, atime);
  }

  public void logUpdateBlocks(String path, FlatINodeFileFeature file) {
    Block[] blocks = new Block[file.numBlocks()];
    int i = 0;
    for (Block b : file.blocks()) {
      blocks[i++] = b;
    }
    fsd.getEditLog().logUpdateBlocks(path, blocks, false);
  }
}
